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

不管现实多么惨不忍睹,都要持之以恒地相信,这只是黎明前短暂的黑暗而已。不要惶恐眼前的难关迈不过去,不要担心此刻的付出没有回报,别再花时间等待天降好运。真诚做人,努力做事!你想要的,岁月都会给你。实战案例:缓存不一致问题的解决(redis+本地缓存caffine),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

一.问题引入

目前在写项目的时候,在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缓存的键和值进行灵活的使用。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/189643.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!