关于 MySQL 和 Redis 一致性问题

2022-03-03 21:33:56 +08:00
 Dganzh

MySQL 作为 DB ,Redis 作为缓存,两个系统会存在一致性问题,最近想到一个方案, 大家说说这种方案有什么优缺点?

写过程:

  1. 先抢锁( lua 搞):redis.setnx(lock_key)
    1.1 失败则自旋直至抢到成功
    1.2 成功,根据更新数据库所需时间设置过期时间,然后进入 2
  2. 更新数据库:db.update()
  3. redis.set(data_key)
  4. redis.del(lock_key)

读过程(根据业务下面 3 选 1 ):

  1. 能接受旧数据的业务,则直接读缓存,redis.get(data_key)。
  2. 要求读到最新数据的业务,则先读 redis.get(lock_key ),如果为空则 redis.get(data_key)返回;不为空则直接读数据库,然后再 redis.setnx(data_key),也就是如果这里存在 data_key 则不设置缓存了。
  3. 上面 2 的过程 redis.get(lock_key)和 redis.get(data_key)之间可能存在其他的写过程,且刚好执行到 2 ,这时候仍可能读到旧数据。所以,这里可以同样先抢锁,redis.setnx(lock_key),抢到锁再 redis.get(data_key),为空则回源数据库然后再设到 redis 。
2786 次点击
所在节点    数据库
10 条回复
fishCatcher
2022-03-03 22:06:09 +08:00
2 回写 redis 的时候如果 db 被更新,那你回写的就是脏数据,后面读到的都是脏数据,肯定是不对的。

3 加锁会阻塞所有其他读写,toc 业务不建议用。

这种一般都有现成的方案,不建议自己造轮子。
bxb100
2022-03-03 22:38:07 +08:00
延时双删
giiiiiithub
2022-03-03 23:05:43 +08:00
现成方案,不要造轮子。

非严格一致可以参考现成方案
https://coolshell.cn/articles/17416.html
bigbyto
2022-03-04 00:45:09 +08:00
你这相当于把操作串行了,而且可靠性依赖 redis 的锁,但 redis 的锁并不可靠。A 获得锁,此时发生 gc stop the world ,锁过期,此时 B 获得锁成功。

这问题的本质就是同时更新两个数据源,如果要求严格的一致性,就需要把所有的操作作为一个原子操作提交,这个实际上是很困难的,比如你可以引入 NPC 协议,这样系统复杂度会大大增加且引入了新的单点,只能在性能和一致性之间做 trade off
Maboroshii
2022-03-04 02:09:04 +08:00
最终一致,不要管 mysql 了 纯 redis 操作
Brian1900
2022-03-04 03:51:48 +08:00
是不是 redis 没用对地方
Tenlearn
2022-03-04 09:50:09 +08:00
@bxb100 延时双删实践上就是扯淡,除了串行没有任何方案能保证完全一致,还是要加过期时间
leafre
2022-03-04 10:53:51 +08:00
必须强一致性,用粗粒度锁,并发冲突概率极大,性能肯定差,实际生产肯定不这样使用。
xuanbg
2022-03-04 12:50:03 +08:00
对于缓存的作用,我发现有很多人其实走进了误区。我们在使用缓存的时候,一定要先明确一点:缓存是用来加速的,仅此而已!
当你给缓存数据赋予更多的职责的时候,缓存也就不是缓存,而是内存数据库了。两个数据库如何保持一致,这是数据库层面的问题,不要在业务层面去解决。不然业务逻辑将会无比复杂,而且根本就没有完美解决方案。

如果你 redis 里面的数据只是缓存,那么就要在享受高效读的好处时,就必须要接受缓存数据不够实时带来的一系列问题。
如果你把 redis 当内存数据库使用,就要接受掉电丢数据的结果。又想读写快,又不想意外丢数据,你想啥呢!
sunqb
2022-03-04 14:31:42 +08:00
为什么需要保证强一致性?你的业务如果有这个需求,就不应该上 mysql 了,直接 oracle 。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/837806

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX