数据库-缓存数据一致性问题

一、问题描述:

当使用DB + cache的架构时,会出现是先更新cache,还是先更新DB的问题。

1.先更新cache,再更新DB:

如果更新cache成功,但是更新DB失败,会导致cache和DB数据的不一致。业务在查询时,查询到的cache数据是更新后的,当cache过期后,经过一次miss,将查询到DB的脏数据。

2.先更新DB,再更新cache:

如果更新DB成功,但是更新cache失败,同样会导致cache和DB数据的不一致。业务在查询时,查询到的cache数据是更新前的脏数据,当cache过期后,经过一次miss,查询到的数据才是正确的数据。
在多线程环境下,假如执行顺序如下:
1.线程A更新DB;
2.然后线程B更新DB;
3.然后线程B更新cache;
4.线程A更新cache。
这样也导致了cache和DB数据的不一致。

二、先淘汰缓存,再更新DB

针对上述问题,有人提出淘汰缓存的策略,具体方法如下:
1.先淘汰cache,如果成功,则更新DB;如果失败则不更新DB,后续可以通过重试来解决失败的问题,但是增加了一次cache的miss。

淘汰策略解决了更新cache的数据一致性问题,但是增加了一次miss cache,淘汰缓存策略特别时候cache和DB数据格式不一样的场景,如cache中的数据是通过DB中的数据计算获得的(如组织架构的树形结构cache,避免对DB的递归查询,需要根据DB计算cache的数据结构),这样也节省了更新缓存的代价。

2.1 并发导致先淘汰缓存的数据不一致性

1.线程A执行数据更新操作,先淘汰cache;
2.线程B执行查询操作,出现了miss cache;
3.线程B查询DB,并将查询到的数据缓存到cache中;
4.线程A此时更新DB。
这样cache的数据和DB的数据出现了不一致,即此时cache保存的是脏数据。

2.2 解决方案一:数据更新queue

针对高并发时cache和DB不一致的问题,可以通过数据更新queue来实现,当要更新数据时,先将要更新的数据key保存到queue中,表示此时数据正在更新,当淘汰cache,执行DB都成功后,将数据从queue队列中删除key。

在数据更新的过程中,先查看cache中是否有对应的key,如果有则返回数据;如果没有数据,则先去queue中查询是否存在对应的key,如果存在则使用while(true)来循环查询cache,并设置超时时间;如果queue中没有对应的key,则判断为miss cache,则读取DB,并将数据缓存到cache中,避免了高并发场景下的数据不一致性。

以上方案也可以解决DB主从延迟的数据一致性问题,即当key在queue中时,程序读取主库,否则读取从库。

2.3 解决方案二:延时双删除策略

采用延时双删除策略,数据更新时具体过程如下:
1.淘汰缓存;
2.更新DB;
3.sleep(100);
4.再次淘汰缓存,避免因为另外线程读取时miss cache导致的脏数据保存到了cache。
但是这种方案有sleep时间难以确定,而且加入步骤4再次淘汰执行失败,也同样导致cache和DB数据的不一致,不过可以通过缓存失效时间来实现最终一致性。

三、先更新DB,再删除cache,即缓存旁路模式(Cache Aside Pattern )

具体操作如下:

1.数据查询

先从cache中获取数据,没有得到,则从DB中获取,成功后将数据放到cache中。

2.数据更新

先更新DB,如果成功,则再执行淘汰缓存,如果执行淘汰缓存失败,则DB回滚。

a.如果数据更新时,淘汰cache失败而不执行DB回滚,可以通过如下方案解决:

方案一:使用MQ保存失败的key

可以通过消息MQ来实现重试,即将淘汰cache失败的key发送到MQ中,然后消费MQ,执行淘汰cache操作,直到淘汰成功。

方案二:使用数据库的binlog

订阅DB的binlog,获取binlog中的数据的key,然后执行淘汰cache中的key,如果失败,则发送key到MQ,后续同方案一。

b.多线程导致的不一致性

线程A执行查询,线程B执行更新,具体过程如下:
1.缓存过期失效;
2.线程A查询,则会miss cache,线程A查询DB得到旧数据,然后准备执行更新cache;
3.线程B更新数据,执行更新DB;
4.线程B淘汰cache;
5.线程A此时执行将旧数据更新cache;

这样会出现数据不一致的情况,但该不一致性出现的条件是,步骤3写入DB操作比步骤2耗时更短,才会出现步骤4先于步骤5。而由于DB的读操作远快于写操作,所以上述场景出现的概率还是很小的。如果这样的概率仍然不可接受,则可以使用“延时双删除策略”双保险策略。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 201,552评论 5 474
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,666评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 148,519评论 0 334
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,180评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,205评论 5 363
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,344评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,781评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,449评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,635评论 1 295
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,467评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,515评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,217评论 3 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,775评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,851评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,084评论 1 258
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,637评论 2 348
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,204评论 2 341

推荐阅读更多精彩内容

  • 2018-10-07 A句:Any threat of monopoly, they argue, is remo...
    P静鸿阅读 201评论 0 0
  • 路过一中十字路口, 红灯闪烁的时间似乎特别长。 远眺斜对面的高压线,起重机,构成一幅画。于是,那一刻的等待变得有点...
    嘟嘟熊的玩美时光阅读 179评论 0 2