热衷学习,热衷生存!

积淀、分享、成长,让本人和别人都能有所播种!

一、Redis三种罕用的缓存读写策略

Redis有三种读写策略别离是:旁路缓存模式策略、读写穿透策略、异步缓存写入策略。

这三种缓存读写策略各有劣势,不存在最佳,须要咱们依据理论的业务场景抉择最合适的。

二、旁路缓存模式(Cache Aside Pattern)

旁路缓存模式是咱们平时应用比拟多的一个缓存读写模式,比拟适宜读申请比拟多的场景。

旁路缓存模式中服务端须要同时保护DBCache,并且是以DB的后果为准。

读写步骤

写:
  • 先更新DB
  • 而后间接删除cache

如下图:

读:
  • cache中读取数据,读取到就间接返回。
  • cache中读取不到的话,就从DB读取返回。
  • 再把数据写到cache中。

如下图:

自我思考

思考这样子的一个问题:“如果在写数据的过程中,能够先删除cache,再更新DB吗?

答案:答案必定是不行的,因为这样子可能造成数据库和缓存数据不统一的问题,比方这个时候有一个数据在DB和缓存都为100,申请1须要将这个数据更新写成200,如果先删除换出再更新数据库的话,在申请1曾经删除缓存然而数据库还没写完的时候,有一个申请2读取数据,首先去缓存读取,发现缓存被删除了,而后去数据库读取失去100(这个时候申请1还没写完)再写入缓存,这个时候申请1写完了,这个时候数据库里数据为200,缓存里为100,不统一。

能够简略形容为:

申请1先把cache中的数据删除 -> 申请2从DB中读取数据 -> 申请1再把DB中的数据更新

紧接着思考:“在写数据的过程中,如果先写BD,再删除cache就不会造成数据不统一了吗?

答案:实践上来说还是会呈现数据不统一的问题,不过概率很小,因为缓存的写入速度是比数据库写入速度快很多。

比方申请1先读数据A,申请2随后写数据A,并且数据A不在缓存中存在的话就会去数据库读取,读取完申请2再更新完并删除缓存,而后申请1把数据A写入缓存,这个时候数据库和缓存就不统一了。

这个过程能够简略的形容为:

申请1从DB读取数据A -> 申请2写更新数据A到数据库再删除cache中的A数据 -> 申请1将数据A写入缓存

毛病

  1. 首次申请的数据肯定不在cache的问题

    解决办法:能够将热点数据提前写入cache中。

  2. 写操作比拟频繁的话导致cache中的数据会被频繁的删除,这样会影响缓存命中率。

    解决办法:

    • 数据库和缓存强始终场景:更新DB的时候同样更新cache,不过须要加一个锁/分布式锁来保障更新cache的时候不存在线程平安问题。
    • 能够短暂的容许数据库和缓存数据不统一的场景:更新DB的时候同样更新cache,然而给缓存加一个比拟短的过期工夫,这样的话就能够保障即便数据不统一的话影响也比拟小。

三、读写穿透(Read/Write Through Pattern)

读写穿透中服务端把cache视为次要数据存储,从中读取数据并将数据写入其中。cache服务负责将此数据读取和写入DB,从而加重应用程序的职责。

读写步骤

写:
  • 先查cachecache中不存在,间接更新DB
  • cache中存在,则先更新cache,而后cache服务本人更新DB(同时更新DBcache)。

如下图:

读:
  • 先从cache中读取数据,读取到间接返回。
  • cache中读取不到,则先从DB加载写入到cache后返回响应。

如下图:

读写穿透理论是在旁路缓存之上进行了封装。在旁路缓存下,产生读申请的时候,如果cache中不存在对应的数据,是由客户端本人负责把数据写入cache,而读写穿透则是cache服务本人来写入缓存,这对客户端是通明的。

和旁路缓存一样,读写穿透也存在首次申请数据肯定不在cache中的问题,对于热点数据能够提前写入缓存中。

四、异步缓存写入(Write Behind Pattern)

异步缓存写入和读写穿透很类似,两者都是由cache服务来负责cacheDB的读写。

两者最大的不同点就是:读写穿透是同步更新DBcache,而异步缓存写入则是只更新cache,不间接更新DB,而是改为异步批量的形式更新DB

很显著,这种形式对数据一致性带来了更大的挑战,比方cache数据可能还没异步更新DBcache服务可能就挂了。

这种策略在咱们平时开发过程中也十分少见,然而不代表它的利用场景少,比方音讯队列中音讯的异步写入磁盘、MySQLInnoDB Buffer Pool机制都用到了这种策略。

异步缓存写入的写性能十分高,非常适合写数据常常变动又对数据一致性要求没那么高的场景下应用,比方浏览量、点赞量等。

参考:https://javaguide.cn/database...