您现在的位置是:首页 >技术交流 >mysql和redis如何保证数据库一致性网站首页技术交流

mysql和redis如何保证数据库一致性

YuanlongWang 2023-05-27 04:00:02
简介mysql和redis如何保证数据库一致性

如果对于小公司的单机服务器来说在更新和删除mysql数据的同时对redis缓存进行更新或者删除就行,一般有两个选择,例如:

  1. 先更新MySQL,后删除(或更新)Redis
  2. 先删除(或更新)Redis,后更新MySQL

但是不管使用其中哪种方式,都存在两个可能的问题:

  1. 由于第一步与第二步并不是原子的,中间会存在较短的时间间隔,如果间隔时间内有请求到达,就可能会访问到不一致的数据。
  2. 可能存在做完第一步,第二步还没来得及做,系统就发生异常的情况;这就会导致MySQL与Redis的数据不一致。

解决方案:

延迟双删策略

延迟双删策略是分布式系统中数据库存储和缓存数据保持一致性的常用策略,但它不是强一致。其实不管哪种方案,都避免不了Redis存在脏数据的问题,只能减轻这个问题,要想彻底解决,得要用到同步锁和对应的业务逻辑层面解决。

先进行缓存清除,再执行update,最后(延迟N秒)再执行缓存清除。进行两次删除,且中间需要延迟一段时间

RedisUtils.del(key);// 先删除缓存    
updateDB(user);// 更新db中的数据    
Thread.sleep(N);// 延迟一段时间,在删除该缓存key    
RedisUtils.del(key);// 先删除缓存

上述中(延迟N秒)的时间要大于一次写操作的时间。原因:如果延迟时间小于写入redis的时间,会导致请求1清除了缓存,但是请求2缓存还未写入的尴尬。。。

延迟双删策略只是一种同步数据库与缓存的手段,在系统并发量不高的情况下可以使用这种方式解决,但是很难控制延迟删除的时间段。

通过MQ异步更新同步数据

这种方式是在更新db操作的写操作的时候,把对应数据通过MQ消息队列的方式发布,redis服务端订阅该消息同步更新redis缓存,但是这种方式要保证消息队列的顺序性,在高并发上也会存在延迟。

canal组件订阅数据库binlog服务

这种方式是,通过订阅mysql的binlog日志,把数据库增删改日志转换成json数据,通过MQ发布消息,redis服务端订阅该消息同步更新redis缓存,这种方式能很好的解决高并发和分布式服务更新数据带来的mysql和redis不一致的情况。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。