page contents

关于redis数据一致性的思考

众所周知的玩笑,计算机科学中只有两个难题:缓存失效和命名。缓存失效,我理解为是如何保证缓存一致性。

attachments-2021-03-mXltFdQr603c917b0ebca.png

众所周知的玩笑,计算机科学中只有两个难题:缓存失效和命名。

缓存失效,我理解为是如何保证缓存一致性。

首先说明,所有的方案都是存在问题的,都不能保证100%的一致性,如果严格要求一致性,那么,把缓存干掉吧....

那么到底要不要用缓存?用缓存的目的是什么?你的业务能接受什么样的数据一致性?使用之前至少需要把这些问题搞清楚。
如果没搞清楚需求,就上缓存,只能说明上缓存只是为了PPT好看并且能多卖一些RMB而已吧。

我个人的理解是,一个技术不应该为了用而用,而是服务于业务的。
假如重新设计一个系统,如果不是已经有个很成熟的系统做样板,我会先全部用DB,然后哪里有问题再改进哪里,不会一上来就决定用某一个中间件。
只用数据库的好处在于实现事务很简单,能保证操作的原子性,并且技术很完善。

如果用了缓存,数据不一致的情况会非常多,事务处理的复杂程度远超我们的想象。只能根据自己的业务,选择一种业务上可以容忍的一致性的方案。
其实往往简单的模型才最可靠,如果没有必要,尽量不用缓存,免得出现各种问题,浪费了时间还得不到想要的效果。

同步缓存的策略分好多好多种,什么实时缓存、异步缓存、定时缓存、消息队列缓存,真要是详细说起来,估计能说一本书,主要是我也不会...
这里就说几种简单、好实现、数据一致性也还算说的过去的方式吧。


一、不主动删除redis,等它自己过期。

一致性 ★☆☆☆☆   实时性 ★★★★★

更新数据库以后,不管redis,等redis中的数据自己过期。查询数据库时,顺便把新值写入redis。

好处是:很简单。坏处是:在没到过期时间之前,数据都是不一致的。比较适合放一些对一致性要求不高,但查询比较多的场景。

过期时间也可以设置的短一些,比如就几秒钟,能提高一些一致性,并防止缓存穿透。


二、更新DB -> 删除redis

一致性 ★★☆☆☆   实时性 ★★★★☆

这种方案的不一致性在于,A更新了DB,A还没有成功删除redis,B又来读redis,这时候B读走的就是旧值。在C读取DB时才会重新将新值放入redis。

在配合key的过期时间的使用,数据一致性能比第一种方案好不少。


三、删除redis -> 更新DB -> 删除redis

一致性 ★★★☆☆   实时性 ★★★☆☆

这种方案的数据不一致性在于,A先删除redis,A在没有完成更新DB时,这时候B读redis,发现没有值,再去读DB,读到了旧值,B还没有把旧值写入redis呢,A就已经完成更新DB的操作并把新值写入redis,等B完成写入redis时,值又被替换成了旧值。


四、删除redis -> 更新DB -> 等待一段时间 ->删除redis

一致性 ★★★★☆   实时性★★☆☆☆

这种方案是对方案三的改进,A先删除redis,A更新完DB之后,等待一段时间(B读DB并写入redis的时间,这个时间需要自己估一下),然后A再删除redis。

其他文章中提到过这种方法被称为“延时双删”,虽然也并不完美,但也能应付大部分的场景了。

 还有很多更高级的保持数据一致性的方法,大家可以自行研究,臣妾做不到了,但好像任何方法都不能保证100%的数据一致性。

选择适合自己业务场景的就好。如果严格要求一致性,那么,把缓存干掉吧....

请轻喷.....


attachments-2021-03-vmjRnr8W603c91a15857f.jpg原文:https://my.oschina.net/MinghanSui/blog/4925940

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
轩辕小不懂
轩辕小不懂

2403 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1478 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章