MySQL和Redis如何保证数据一致性?
认真看完哦~ ~ ~ ~
何保证数据一致性。这里主要探讨四种方案
1. 先更新数据库,后更新缓存 (这种场景一般是没有人使用的)
这种场景一般是没有人使用的,主要原因是在更新缓存那一步,为什么呢?因为有的业务需求缓存中存在的值并不是直接从数据库中查出来的,有的是需要经过一系列计算来的缓存值,那么这时候后你要更新缓存的话其实代价是很高的。如果此时有大量的对数据库进行写数据的请求,但是读请求并不多,那么此时如果每次写请求都更新一下缓存,那么性能损耗是非常大的。
举个例子比如在数据库中有一个值为 1 的值,此时我们有 10 个请求对其每次加一的操作,但是这期间并没有读操作进来,如果用了先更新数据库的办法,那么此时就会有十个请求对缓存进行更新,会有大量的冷数据产生,如果我们不更新缓存而是删除缓存,那么在有读请求来的时候那么就会只更新缓存一次。
我的理解:数据库正常更新,缓存更新失败,用户读取的不是最新的数据,缓存数据库不一致.
2. 先更新数据库,后删除缓存
问题:这一种情况也会出现问题,比如更新数据库成功了,但是在删除缓存的阶段出错了没有删除成功,那么此时再读取缓存的时候每次都是错误的数据了。
3. 先更新缓存,后更新数据库
这一种情况应该不需要我们考虑了吧,和第一种情况是一样的。
我的理解:缓存正常更新,数据库失败,数据库不是最新的数据,缓存数据库不一致.
4. 先删除缓存,后更新数据库
此时来了两个请求,请求 A(更新操作) 和请求 B(查询操作)
- 请求 A 会先删除 Redis 中的数据,然后去数据库进行更新操作
- 此时请求 B 看到 Redis 中的数据时空的,会去数据库中查询该值,补录到 Redis 中
- 但是此时请求 A 并没有更新成功,或者事务还未提交
那么这时候就会产生数据库和 Redis 数据不一致的问题。如何解决呢?其实最简单的解决办法就是延时双删的策略。
延时双删
我的理解:对于写的请求 先删除缓存 在更新数据库 睡眠1s 在删除缓存
但是上述的保证事务提交完以后再进行删除缓存还有一个问题,就是如果你使用的是 Mysql 的读写分离的架构的话,那么其实主从同步之间也会有时间差。
- 请求 A 更新操作,删除了 Redis
- 请求主库进行更新操作,主库与从库进行同步数据的操作
- 请 B 查询操作,发现 Redis 中没有数据
- 去从库中拿去数据
- 此时同步数据还未完成,拿到的数据是旧数据
此时的解决办法就是如果是对 Redis 进行填充数据的查询数据库操作,那么就强制将其指向主库进行查询
参考juejin.cn/post/6850418121754050567
本作品采用《CC 协议》,转载必须注明作者和本文链接
第四种不就是第一种...
额。。。