面试/工做必备!3种经常使用的缓存读写策略!

推荐👍:接近100K star 的Java学习/面试指南:JavaGuidegit

看到不少小伙伴简历上写了“熟练使用缓存”,可是被我问到“缓存经常使用的3种读写策略”的时候却一脸懵逼。github

在我看来,形成这个问题的缘由是咱们在学习 Redis 的时候,可能只是简单了写一些 Demo,并无去关注缓存的读写策略,或者说压根不知道这回事。面试

可是,搞懂3种常见的缓存读写策略对于实际工做中使用缓存以及面试中被问到缓存都是很是有帮助的!数据库

下面我会简单介绍一下本身对于这 3 种缓存读写策略的理解。缓存

另外,这3 种缓存读写策略各有优劣,不存在最佳,须要咱们根据具体的业务场景选择更适合的。安全

我的能力有限。若是文章有任何须要补充/完善/修改的地方,欢迎在评论区指出,共同进步!——爱大家的 Guide 哥异步

Cache Aside Pattern(旁路缓存模式)

Cache Aside Pattern 是咱们平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景。分布式

Cache Aside Pattern 中服务端须要同时维系 DB 和 cache,而且是以 DB 的结果为准。ide

下面咱们来看一下这个策略模式下的缓存读写步骤。性能

  • 先更新 DB
  • 而后直接删除 cache 。

简单画了一张图帮助你们理解写的步骤。

:

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

简单画了一张图帮助你们理解读的步骤。

你仅仅了解了上面这些内容的话是远远不够的,咱们还要搞懂其中的原理。

好比说面试官极可能会追问:“在写数据的过程当中,能够先删除 cache ,后更新 DB 么?

答案: 那确定是不行的!由于这样可能会形成数据库(DB)和缓存(Cache)数据不一致的问题。为何呢?好比说请求1 先写数据A,请求2随后读数据A的话就颇有可能产生数据不一致性的问题。这个过程能够简单描述为:

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

当你这样回答以后,面试官可能会紧接着就追问:“在写数据的过程当中,先更新DB,后删除cache就没有问题了么?

答案: 理论上来讲仍是可能会出现数据不一致性的问题,不过几率很是小,由于缓存的写入速度是比数据库的写入速度快不少!

好比请求1先读数据 A,请求2随后写数据A,而且数据A不在缓存中的话也有可能产生数据不一致性的问题。这个过程能够简单描述为:

请求1从DB读数据A->请求2写更新数据 A 到数据库并把删除cache中的A数据->请求1将数据A写入cache。

如今咱们再来分析一下 Cache Aside Pattern 的缺陷

缺陷1:首次请求数据必定不在 cache 的问题

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

缺陷2:写操做比较频繁的话致使cache中的数据会被频繁被删除,这样会影响缓存命中率 。

解决办法:

  • 数据库和缓存数据强一致场景 :更新DB的时候一样更新cache,不过咱们须要加一个锁/分布式锁来保证更新cache的时候不存在线程安全问题。
  • 能够短暂地容许数据库和缓存数据不一致的场景 :更新DB的时候一样更新cache,可是给缓存加一个比较短的过时时间,这样的话就能够保证即便数据不一致的话影响也比较小。

Read/Write Through Pattern(读写穿透)

Read/Write Through Pattern 中服务端把 cache 视为主要数据存储,从中读取数据并将数据写入其中。cache 服务负责将此数据读取和写入 DB,从而减轻了应用程序的职责。

这种缓存读写策略小伙伴们应该也发现了在平时在开发过程当中很是少见。抛去性能方面的影响,大几率是由于咱们常用的分布式缓存 Redis 并无提供 cache 将数据写入DB的功能。

写(Write Through):

  • 先查 cache,cache 中不存在,直接更新 DB。
  • cache 中存在,则先更新 cache,而后 cache 服务本身更新 DB(同步更新 cache 和 DB)。

简单画了一张图帮助你们理解写的步骤。

读(Read Through):

  • 从 cache 中读取数据,读取到就直接返回 。
  • 读取不到的话,先从 DB 加载,写入到 cache 后返回响应。

简单画了一张图帮助你们理解读的步骤。

Read-Through Pattern 实际只是在 Cache-Aside Pattern 之上进行了封装。在 Cache-Aside Pattern 下,发生读请求的时候,若是 cache 中不存在对应的数据,是由客户端本身负责把数据写入 cache,而 Read Through Pattern 则是 cache 服务本身来写入缓存的,这对客户端是透明的。

和 Cache Aside Pattern 同样, Read-Through Pattern 也有首次请求数据必定再也不 cache 的问题,对于热点数据能够提早放入缓存中。

Write Behind Pattern(异步缓存写入)

Write Behind Pattern 和 Read/Write Through Pattern 很类似,二者都是由 cache 服务来负责 cache 和 DB 的读写。

可是,两个又有很大的不一样:Read/Write Through 是同步更新 cache 和 DB,而 Write Behind Caching 则是只更新缓存,不直接更新 DB,而是改成异步批量的方式来更新 DB。

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

这种策略在咱们平时开发过程当中也很是很是少见,可是不表明它的应用场景少,好比消息队列中消息的异步写入磁盘、MySQL 的 InnoDB Buffer Pool 机制都用到了这种策略。

Write Behind Pattern 下 DB 的写性能很是高,很是适合一些数据常常变化又对数据一致性要求没那么高的场景,好比浏览量、点赞量。

个人Github地址:Snailclimb - Overview

相关文章
相关标签/搜索