Cache Aside Pattern(缓存模式)解析

开发 开发工具 前端
在《究竟先操作缓存,还是数据库?》,有同学在评论提出,相关方案违背了“Cache Aside Pattern”的原则,故今天聊一聊Cache Aside Pattern。

在《究竟先操作缓存,还是数据库?》,有同学在评论提出,相关方案违背了“Cache Aside Pattern”的原则,故今天聊一聊Cache Aside Pattern。

[[236538]]

另外,在讨论技术方案时,尽量不说:

  • “你是错的,应该怎么样”
  • “facebook不是这样,所以你是错的”

画外音:凭什么facebook就是真理?它的方案只是适合它的业务而已。

说明适用场景,说明来龙去脉,说明前因后果,比具体使用什么方案更重要。

什么是“Cache Aside Pattern”?

答:旁路缓存方案的经验实践,这个实践又分读实践,写实践。

对于读请求

  • 先读cache,再读db
  • 如果,cache hit,则直接返回数据
  • 如果,cache miss,则访问db,并将数据set回缓存

如上图:

  • 先从cache中尝试get数据,结果miss了
  • 再从db中读取数据,从库,读写分离
  • ***把数据set回cache,方便下次读***

画外音:这一点上,与《究竟先操作缓存,还是数据库?》说的是一致的。

对于写请求

  • 淘汰缓存,而不是更新缓存
  • 先操作数据库,再淘汰缓存

如上图:

(1)***步要操作数据库,第二步操作缓存

画外音:这一点上,与《究竟先操作缓存,还是数据库?》说的不一致,也是评论反驳比较激烈的地方。

(2)缓存,采用delete淘汰,而不是set更新

画外音:这一点上,与《缓存,究竟是淘汰,还是修改?》说的是一致的。

Cache Aside Pattern为什么建议淘汰缓存,而不是更新缓存?

答:如果更新缓存,在并发写时,可能出现数据不一致。

如上图所示,如果采用set缓存。

在1和2两个并发写发生时,由于无法保证时序,此时不管先操作缓存还是先操作数据库,都可能出现:

  • 请求1先操作数据库,请求2后操作数据库
  • 请求2先set了缓存,请求1后set了缓存

导致,数据库与缓存之间的数据不一致。

所以,Cache Aside Pattern建议,delete缓存,而不是set缓存。

Cache Aside Pattern为什么建议先操作数据库,再操作缓存?

答:如果先操作缓存,在读写并发时,可能出现数据不一致。

如上图所示,如果先操作缓存。

在1和2并发读写发生时,由于无法保证时序,可能出现:

  • 写请求淘汰了缓存
  • 写请求操作了数据库(主从同步没有完成)
  • 读请求读了缓存(cache miss)
  • 读请求读了从库(读了一个旧数据)
  • 读请求set回缓存(set了一个旧数据)
  • 数据库主从同步完成

导致,数据库与缓存的数据不一致。

所以,Cache Aside Pattern建议,先操作数据库,再操作缓存。

Cache Aside Pattern方案存在什么问题?

答:如果先操作数据库,再淘汰缓存,在原子性被破坏时:

  • 修改数据库成功了
  • 淘汰缓存失败了

导致,数据库与缓存的数据不一致。

如何解决这类问题呢?

答:详见《究竟先操作缓存,还是数据库?》。

【本文为51CTO专栏作者“58沈剑”原创稿件,转载请联系原作者】

戳这里,看该作者更多好文

责任编辑:赵宁宁 来源: 51CTO专栏
相关推荐

2023-08-03 08:52:10

缓存数据逐出数据

2009-09-22 10:50:04

Hibernate c

2012-08-27 10:52:20

.NET架构观察者模式

2021-12-01 07:38:27

设计模式规格模式Specificati

2021-11-29 09:38:12

设计模式对象池模式Object Pool

2019-08-16 10:46:46

JavaScript工厂模式抽象工厂模式

2023-05-05 18:38:33

多级缓存Caffeine开发

2021-06-29 19:26:29

缓存Spring CachSpring

2024-03-14 08:57:04

高并发缓存更新

2012-08-22 10:10:25

单态单态设计设计模式

2011-12-10 19:17:12

webOS

2010-09-26 08:46:06

HTML 5Cache Manif

2014-11-04 10:34:27

JavaCache

2024-02-19 08:38:34

建造者模式Android设计模式

2018-11-30 15:17:38

CPUCache缓存行

2021-03-30 10:50:18

Linux内存命令

2023-10-30 07:56:46

Spring缓存

2020-12-23 13:14:00

LinuxLinux内存Swap

2018-05-28 08:54:45

SparkRDD Cache缓存

2010-08-30 14:31:43

Cache
点赞
收藏

51CTO技术栈公众号