失效链接处理 |
Redis 基础:常见的缓存更新策略有哪几种 PDF 下载
本站整理下载:
相关截图:
主要内容:
Cache Aside Pattern 是我们平时使⽤⽐较多的⼀个缓存读写模式,⽐较适合读
请求⽐较多的场景。
Cache Aside Pattern 中服务端需要同时维系数据库(后⽂简称 db)和缓存(后
⽂简称 cache),并且是以 db 的结果为准。
下⾯我们来看⼀下这个策略模式下的缓存读写步骤。
写 :
1. 先更新 db;
2. 直接删除 cache 。
简单画了⼀张图帮助⼤家理解写的步骤。
读 :
1. 从 cache 中读取数据,读取到就直接返回;
2. cache 中读取不到的话,就从 db 中读取数据返回;
3. 再把 db 中读取到的数据放到 cache 中。
简单画了⼀张图帮助⼤家理解读的步骤。
你仅仅了解了上⾯这些内容的话是远远不够的,我们还要搞懂其中的原理。
⽐如说⾯试官可能会问你:“为什么删除 cache,⽽不是更新 cache?”
主要原因有两点:
1. 对服务端资源造成浪费 :删除 cache 更加直接,这是因为 cache 中存放的
⼀些数据需要服务端经过⼤量的计算才能得出,会消耗服务端的资源,是⼀
笔不晓得开销。如果频繁修改 db,就能会导致需要频繁更新 cache,⽽
cache 中的数据可能都没有被访问到。
2. 产⽣数据不⼀致问题 :并发场景下,更新 cache 产⽣数据不⼀致性问题的概
率会更⼤(后⽂会解释原因)。
⾯试官很可能会追问:“在写数据的过程中,可以先删除 cache ,后更新 db
么?”
答案: 那肯定是不⾏的!因为这样可能会造成 数据库(db)和缓存(Cache)数
据不⼀致的问题。
举例:请求 1 先写数据 A,请求 2 随后读数据 A 的话,就很有可能产⽣数据不⼀
致性的问题。这个过程可以简单描述为:
1. 请求 1 先把 cache 中的 A 数据删除;
2. 请求 2 从 db 中读取数据;
3. 请求 1 再把 db 中的 A 数据更新。
这就会导致请求 2 读取到的是旧值。
当你这样回答之后,⾯试官可能会紧接着就追问:“在写数据的过程中,先更新
db,后删除 cache 就没有问题了么?”
答案: 理论上来说还是可能会出现数据不⼀致性的问题,不过概率⾮常⼩,因为
缓存的写⼊速度是⽐数据库的写⼊速度快很多。
举例:请求 1 先读数据 A,请求 2 随后写数据 A,并且数据 A 在请求 1 请求之前
不在缓存中的话,也有可能产⽣数据不⼀致性的问题。这个过程可以简单描述
为:
1. 请求 1 从 db 读数据 A;
2. 请求 2 更新 db 中的数据 A(此时缓存中⽆数据 A ,故不⽤执⾏删除缓存操
作 );
3. 请求 1 将数据 A 写⼊ cache。
这就会导致 cache 中存放的其实是旧值。
现在我们再来分析⼀下 Cache Aside Pattern 的缺陷。
缺陷 1:⾸次请求数据⼀定不在 cache 的问题
解决办法:可以将热点数据可以提前放⼊ cache 中。
缺陷 2:写操作⽐较频繁的话导致 cache 中的数据会被频繁被删除,这样会影响
缓存命中率 。
解决办法:
数据库和缓存数据强⼀致场景 :更新 db 的时候同样更新 cache,不过我们
需要加⼀个锁/分布式锁来保证更新 cache 的时候不存在线程安全问题。
可以短暂地允许数据库和缓存数据不⼀致的场景 :更新 db 的时候同样更新
cache,但是给缓存加⼀个⽐较短的过期时间,这样的话就可以保证即使数
据不⼀致的话影响也⽐较⼩。
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 和 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 的写性能⾮常⾼,⾮常适合⼀些数据经常变化⼜对数
据⼀致性要求没那么⾼的场景,⽐如浏览量、点赞量。
|