实战案例:缓存不一致问题的解决(redis+本地缓存caffine)

一.问题引入

目前在写项目的时候,在B端查看文章,A端修改文章。为了增加效率,以及防止堆内存溢出,在B端选择本地缓存文章的方案。但是目前出现了A端对文章修改之后,B端读的还是旧数据,出现了缓存不一致的问题

二.解决方案

1. 本地缓存失效策略

在这里插入图片描述
A端只要有文章修改,就将对应的caffineKey缓存删除,B端就会重新去读新的数据.

问题:
由于在线上环境下,服务是集群的形式部署的,因此在使缓存失效的时候是随机使一个节点的缓存失效,不能所有的节点都失效,所以会存在某些节点仍然会读到旧缓存的问题。

2. 加入redis,使redis失效策略

在这里插入图片描述
由于redis是分布式缓存,在集群下,所有节点都能读到

2.1 redisKey与caffineKey一一对应

A端只要有文章修改,就将对应的redisKey缓存删除,B端先判断某篇文章的redisKey是否存在,存在则说明该文章没有发生变更,去caffine拿相应缓存,否则去查数据库。

问题:
理想条件下这种方案是比较好的,但是目前A段在修改文章的时候,粒度不能进行控制,对于不同的操作,修改文章的篇数不同,有是可能会改动到所有的文章,这是需要删除所有的redis缓存,但是在遍历某文件夹下所有的key是一个十分消耗性能的操作,容易造成redis崩溃,所以不推荐。

2.2 redisKey只存一个控制所有caffineKey

目前的想法是,redisKey只存一个,只要有文章的变更就让redisKey失效,那么当访问文章时,先查看是否有redisKey缓存,如果没有直接去查数据库,不去查缓存,查了数据库之后,更新缓存。

问题:
如果有A,B两篇文章都进行了缓存,但是此时A文章进行了修改,因此redisKey失效,当B再次读取的时候,redisKey重新失效,再去读A,由于A中的缓存未发生变更,因此读到的还是旧数据

2.2 redisKey只存一个控制所有caffineKey同时redisKey和caffineKey的值中时间戳

在这里插入图片描述
redis和caffine缓存中存储时间戳,如果redis和caffine缓存时间戳相等,说明caffine缓存中的数据没有落后

问题:
因为每次当caffine缓存中的时间戳和redis中的时间戳不一致就会去重新插入redis,这样就会造成,只要有一片文章重新去数据库查了,就会导致之前的caffine缓存都失效,失去了缓存的意义。

3.redis缓存作为文章发生变更的标识

只有在文章发生变更的时候才会进行redis缓存的插入/更新操作
在这里插入图片描述
这个时候只是把redis缓存作为文章发生变更的标识,在查文章的时候也不会先去看redis是否存在,而是先看本地缓存是否存在,然后再看redis是否存在(是否发生变更),以及如果redis缓存存在,时间戳的比较(判断该本地缓存是在变更前写入的还是变更后写入的)

三.总结

通过这个实践,还是得从一开始弄明白整个方案设计的可能存在的问题,以及对于redis缓存的键和值进行灵活的使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/288959.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《数据结构、算法与应用C++语言描述》- 最小赢者树模板的C++实现

赢者树 完整可编译运行代码见:Github::Data-Structures-Algorithms-and-Applications/_30winnerTree 比赛规则 假定有 n 个选手参加一次网球比赛。比赛规则是“突然死亡法”(sudden-death mode):一名选手只要输掉一场球,就被淘汰。一对一对…

在mt4上怎么查看CHFJPY品种的合约细则?

在MetaTrader 4 (MT4) 上查看CHFJPY品种的合约细则的方法如下: FXCM福汇官方个人注册登录流程 1.打开MT4软件并登录到您的交易账户。 2.在MT4界面的"市场观察"窗格中,找到并右键单击"CHFJPY"货币对。如果您无法找到"市场观察…

贪吃蛇(三)绘制蛇身

绘制蛇身的逻辑不难,存储上面使用结构体。 第一行和第十九行绘制--其它行,绘制|,分别在头尾处。 (1) 扫描蛇身,如果扫描到则绘制[]。 (2) 扫描蛇身,如果扫描不到则绘制空白。 #include"curses.h"struct Sn…

鸿蒙ArkTS语言介绍与TS基础法

1、ArkTS介绍 ArkTS是HarmonyOS主力应用开发语言,它在TS基础上,匹配ArkUI框架,扩展了声明式UI、状态管理等响应的能力,让开发者以更简洁、更自然的方式开发跨端应用。 JS 是一种属于网络的高级脚本语言,已经被广泛用…

Pixel Nerf代码阅读

Input: 图像的 分辨率是 300*400; 每个场景里面有 49张 Training 的图像。 SB: scene batch 场景的个数; 4 NV: number input ,每个场景的视角,也就是图像的数量; 49 每条光线首先…

微电网优化(Matlab复现)— 微电网两阶段鲁棒优化经济调度方法_刘一欣

论文链接:微电网两阶段鲁棒优化经济调度方法 - 中国知网 代码链接:https://m.tb.cn/h.5Mg7fCo?tkhnpmWgZiv2R 复现效果: 运行环境:Matlab 2020bCplexyalmip 1 微电网结构 图 1 所示为典型的微电网结构,由可控分布式…

Python Opencv实践 - 手部跟踪

使用mediapipe库做手部的实时跟踪,关于mediapipe的介绍,请自行百度。 mediapipe做手部检测的资料,可以参考这里: MediaPipe Hands: On-device Real-time Hand Tracking 论文阅读笔记 - 知乎论文地址: https://arxiv.org/abs/2006…

Mysql之约束上篇

Mysql之约束上篇 约束的概述为什么需要约束什么是约束约束的分类 非空约束作用关键字特点添加非空约束删除非空约束 唯一性约束关键字特点添加唯一约束关于复合唯一约束删除唯一约束查看索引 主键约束(非空唯一性约束)作用关键字特点添加主键约束关于复合主键删除主键约束 约束…

排序算法——快排

快速排序算法最早是由图灵奖获得者Tony Hoare设计出来的,他在形式化方法理论以 及ALGOL.60编程语言的发明中都有卓越的贡献,是20世纪最伟大的计算机科学家之—。 而这快速排序算法只是他众多贡献中的—个小发明而已。 快速排序(Quick Sort)的基本算法思…

类和对象(中篇)

类的六个默认成员函数 如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数: 用户没有显式实现,编译器会…

那些类型有Class对象

演示哪些类型有 Class对象 /*** 演示哪些类型有 Class对象*/ public class AllTypeClass {public static void main(String[] args) {Class<String> stringClass String.class; //外部类Class<Serializable> serializableClass Serializable.class;//接口Class&…

你知道跨站脚本攻击吗?一篇带你了解什么叫做XSS

1.XSS简介 &#xff08;1&#xff09;XSS简介 XSS作为OWASP TOP 10之一。 XSS中文叫做跨站脚本攻击&#xff08;Cross-site scripting&#xff09;&#xff0c;本名应该缩写为CSS&#xff0c;但是由于CSS&#xff08;Cascading Style Sheets&#xff0c;层叠样式脚本&#x…