缓存读写策略

Cache Aside Pattern(旁路缓存模式)

Cache Aside Pattern适合读多写少的场景。Cache Aside Pattern中服务端需要同时维系DB和cache,并且最终的结果以DB为准。

下面是该策略模式下缓存读写步骤。

写:

  • 首先更新数据库
  • 然后直接删除cache中的数据

下图展示了该模式下的写步骤:

读:

  • 从cache中读取数据,如果缓存命中就直接返回
  • 如果cache未命中,就从数据库中读取数据并返回
  • 将读取的数据放入缓存中

下图展示了该模式下的读步骤:

Cache Aside Pattern的缺陷:

  1. 首次请求的数据一定不在cache中

    解决方案:将热点数据提前放入cache中

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

    解决方案:

    • 数据库和缓存强一致场景:更新数据库的时候同时更新cache(需要加锁/分布式锁来保证更新cache的时候不存在线程安全问题)。
    • 可以短暂地允许数据库和缓存数据不一致的场景:更新数据库的时候同时更新cache,但是给缓存加一个比较短的过期时间,这样就可以保证即使数据不一致但影响比较小。

Read/Write Through Pattern(读写穿透)

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

下面是该策略模式下缓存读写步骤。

写:

  • 先查询cache,cache中不存在,直接更新数据库
  • cache中存在,则先更新cache,然后cache服务自己更新数据库(同步更新cache和数据库)

下图展示了该模式下的写步骤:

读:

  • 从cache中读取数据,如果缓存命中就直接返回
  • 如果缓存不命中,先从数据库中加载,写入到cache后返回响应

下图展示了该模式下的读步骤:

Read-Through Pattern实际只是再Cache-Aside Pattern之上进行了封装。在Cache-Aside Pattern下,发生读请求时,如果cache中不存在对应的数据,是由客户端负责把数据写入到cache,而Read-Through Pattern则是cache服务自己来完成缓存的写入,这个步骤对客户端是透明的。

和Cache Aside Pattern一样,Read-Through Pattern也存在首次请求数据一定不在cache中的问题,因此对于热点数据可以提前放入缓存中。

Wirte Behind Pattern(异步缓存写入)

Write Behind Pattern和Read/Write Through Pattern类似,两者都是由cache服务来负责cache和数据库的读写。但是Read/Write Through是同步更新cache和数据库,而Write Behind Pattern则是只更新缓存,数据库的更新方式改为异步批量更新。

这种方式对数据一致性有很大的挑战,比如cache数据可能还没有更新到数据库,cache服务可能就已经死掉了。这种策略在我们平时开发过程中也非常非常少见,但是不代表它的应用场景少,比如消息队列中消息的异步写入磁盘、MySQL 的 InnoDB Buffer Pool 机制都用到了这种策略。Write Behind Pattern 下数据库的写性能非常高,非常适合一些数据经常变化又对数据一致性要求没那么高的场景,比如浏览量、点赞量。

作者

Cindy

发布于

2022-08-30

许可协议

CC BY-NC-SA 4.0

Your browser is out-of-date!

Update your browser to view this website correctly.&npsb;Update my browser now

×