我所知道的缓存知识--Cache-Aside && Cache-As-SoR

本章主要内容:

         Cache-Aside && Cache-As-SoR 介绍

         Cache-Aside的使用需要考虑的问题

         那么如何保证数据库和缓存的原子新

         那些数据适合淘汰,那些数据适合更新

 

1. Cache-Aside:该模式对缓存的关注点主要是在与业务方。即缓存的更新,删除与数据库的操作,以及他们之间的先后顺序由业务方实现。

读场景,先从缓存中读取数据,如果没有命中,则回源到存储系统并将源数据放入缓存供下次使用。

写场景,先将数据写入到存储系统中,写入后同步将数据写入缓存。

扫描二维码关注公众号,回复: 4705551 查看本文章

此模式优势在于利用数据库比较成熟的高可用机制,数据库写入成功,则进行缓存数据更新,如果缓存数据写入失败,可以发起重试。

2. Cache-As-SoR:把数据库+缓存作为一个整体(SoR),业务方不关心缓存与数据库之间的关系,对业务方而已,只需要两个动作,get/write。 至于业务读取缓存数据,缓存不存在,或者过期要怎么去更新。并不是业务需要更新的事情。而是SoR这个系统应该关心。

Cahe-As-SoR主要又分为:

(1) Read-Through:

业务代码获取数据时,执行get操作,SoR系统读取缓存,如果没有,SoR系统则从数据库加载,然后放入缓存(存储端自己实现cache-aside),然后返回给业务代码

(2) Write-Through:

Write-Through被称之为穿透写模式,业务代码首先调用write操作,然后由SoR更新缓存数据和存储数据。

(3)Write-Behind:

业务代码只更新到缓存数据,什么时候更新到数据库,由SoR中缓存和数据库的同步策略决定(异步),可以实现批量写/合并写/延时/限流

 

3.那么对于在现实中,要实现Cache-Aside 我们要考虑什么?

(1) 对于写操作,是先写cache 还是 DB?

(2) 先写Cache,如果Cache写成功,DB写失败,造成数据不一致

(3) 先写DB,如果DB写成功,Cache写失败,造成不一致

(4) 对于写操作,是更新缓存还是淘汰缓存?

对于问题(4),更新缓存会出现(1)(2)中问题,那么如果是淘汰呢?

 a. 先淘汰Cache,然后写数据库,那么即使DB写入失败,下次读时,会从数据库中重新读取数据,只是多了一部读取操作。但保证了数据的一致性。所以建议淘汰缓存,而不是更新缓存。

b. 但在高并发中会存在问题,比如这样的场场景:

               甲对缓存key1进行写操作,key1原本为1,甲要更新key1=2。

               同时这时候乙要读取Key1值。由于我们无法控制甲和乙的先后顺序。

               甲可能先淘汰了key1,并准备将数据写入db,这时候乙读取缓存,发现key1不存在。

               从数据库中读取数据,并设置key1(甲没有完成数据的写)。然后甲完成了对数据库的写。

              现在在db key1=2,在cache中 key1=2。数据不一致

对于查询非常频繁的业务不适用,因为执行删除的同时,已经有另一个系统来读缓存了,会造成缓存穿透,导致大量请求向DB请求数据(可以防止)

c. 先操作数据,再淘汰缓存,但也会出现一半成功,一半失败的情况

 

4.那么如何保证数据库和缓存的原子新:

  a. 保持DB和缓存的最终一致。比如先操作数据库,在操作缓存,如果操作缓存失败,则记录这个失败(放入队列),后台开启脚本,专门处理失败这些数据。(对数据一致性不是高要求的)

 b. 可以通过canal实现缓存同步

 c. 对于一致性要求不那么高的,量小,可以考虑定期同步,以保持最终一致

 d. 或者设置合理的过期时间

 e. 对于强一致的数据,则需要通过分布式锁,或者读写都只操作数据

5. 那些数据适合淘汰,那些数据适合更新?

是淘汰还是更新,需要考虑成本问题。

如果只是简单的更新操作,并入key=1  更新 为 key=2 这样简单的操作。更新比较合适

但是类似xlm,json等数据,需要获取,然后反序列化,业务更新json/xlm中的某个值。然后在序列化,再更新缓存。这个过程比较复杂,而且消耗比较多。不如之间淘汰了。

所以对于只是简单的 类似 1->2 操作,时候更新,但由更新某个键需要的操作比较复杂,建议delete

 

站在巨人的肩膀上成长,文章思想和经验来自各类大神 参考 《深入分布式缓存从原理到实践》  公众号:架构师之路

 

猜你喜欢

转载自blog.csdn.net/H_L_S/article/details/85011320