三大缓存读写策略
Cache的读写策略是指在计算机系统中,对于缓存(Cache)的数据读取和写入操作所采取的策略和方法。不同读写策略可根据系统需求和应用场景进行选择和配置,以达到最优性能和效果。本文简单记录了三大缓存读写策略旁路缓存模式、读写穿透、异步缓存写入,它们各有优劣不存在最佳模式,根据具体的业务场景选择适合的缓存读写模式。
参考文章:
Cache Aside Pattern(旁路缓存模式)
Cache Aside Pattern :平时使用比较多的一个缓存读写模式,比较适合读请求比较多的场景。该策略中服务端需要同时维系 db 和 cache,并且以 db 的结果为准。
缓存读写步骤
写:由应用先更新 db;然后应用再直接删除 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 请求前不在缓存中时也有可能产生数据不一致性的问题。该过程实际是:请求 1 从 db 读数据 A → 请求 2 更新 db 中的数据 A(此时缓存中无数据 A ,故不用执行删除缓存操作 ) → 请求 1 将数据 A 写入 cache
缺陷
缺陷 1:首次请求数据一定不在 cache。解决办法如下:
数据预热。将热点数据提前放入 cache。
缺陷 2:写操作频繁导致 cache 中数据被频繁删除影响缓存命中率 。解决办法如下:
数据库和缓存数据强一致:更新 db 的时同样更新 cache,需加一个锁/分布式锁保证更新 cache 时不存在线程安全问题。
可短暂地允许数据库和缓存数据不一致:更新 db 时同样更新 cache,但给缓存一个较短过期时间,如此数据不一致影响也较小。
Read/Write Through Pattern(读写穿透)
该策略中服务端把 cache 视为主要数据存储,从中读取数据并将数据写入其中。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 服务自己来写入缓存的,这对客户端是透明的。
Write Behind Pattern(异步缓存写入)
和 Read/Write Through Pattern 相似都是由 cache 服务来负责 cache 和 db 的读写。
但不同的是Read/Write Through 同步更新 cache 和 db,而 Write Behind 只更新缓存不直接更新 db,而是异步批量更新 db。
这种方式对数据一致性带来了更大的挑战,比如 cache 数据可能还没异步更新 db 的话,cache 服务可能就就挂掉了。平时开发非常少见,但消息队列中消息的异步写入磁盘、MySQL 的 Innodb Buffer Pool 机制都用到了这种策略。
Write Behind Pattern 下 db 的写性能非常高,非常适合一些数据经常变化又对数据一致性要求没那么高的场景,比如浏览量、点赞量。




