701 字
4 分钟
3种常用缓存读写策略
2025-03-20
无标签

Cache Aside Pattern(旁路缓存模式)#

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

Cache Aside Pattern 中服务端需要同时维系 db 和 cache,并且是以 db 的结果为准。

读写步骤#

  • 先更新 db
  • 然后直接删除 cache 。

cache-aside-write

:

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

cache-aside-read

面试官很可能会追问:“在写数据的过程中,可以先删除 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,但是给缓存加一个比较短的过期时间,这样的话就可以保证即使数据不一致的话影响也比较小。
3种常用缓存读写策略
https://fuwari.vercel.app/posts/cache/
作者
Lettle
发布于
2025-03-20
许可协议
CC BY-NC-SA 4.0