Redis--如何保证redis和数据库中数据双写一致性

文章目录

        • 如何保持redis和数据库中数据双写一致性

如何保持redis和数据库中数据双写一致性

如果出现数据一致性问题,一般会想到以下两种解决思路。

  1. 先更新数据库,再更新缓存
  • 如果是采用先更新数据库,再更新缓存的方案,会有这样一个问题。假设缓存更新失败,就会导致数据库和 Redis 中的数据不一致。
  1. 先删除缓存,再更新数据库
  • 那如果是先删除缓存,再更新数据库,理想情况是应用下次访问 Redis 的时候,发现 Redis 里面的数据是空的,就从数据库加载保存到 Redis 里面,那么数据是一致的。

  • 假设缓存删除成功,但数据库更新失败。此时新的请求过来,就去数据库中读取旧数据更新到缓存中,此时数据库与缓存中的数据一样是一致的。

  • 当然这种方式也可能出现redis和数据库数据不一致的情况。如下述情况:

    • MySQL使用主从分离的架构,造成redis和数据库数据不一致的情况:系统同时进入两个请求,一个写请求,一个读请求。写请求删除缓存,并且更新主库的数据,但还没同步给从库,读请求就判断缓存为空,去从库里读信息了,拿到旧数据后写入缓存,写请求完成更新后就发生了缓存和数据库不一致的问题。
    • 解决方法是可以采用延时双删策略,先删除缓存,再写数据库,异步等待一段时间后,再次淘汰缓存(这里设置时间主要是保证读请求结束,写请求可以删除读请求造成的缓存脏数据,需要自行评估确定)。该方案解决了高并发情况下,同时有读请求和写请求时导致的不一致问题,读取速度快,但是可能会导致短时间出现脏数据。为了保证第二次删除不会失败,可以加入重试机制(缓存删除失败,将需要删除的key发送给消息队列,自己在消费信息,获得要删除的key,重新删除)保证删除一定成功。
  • 但是在极端情况下,并不能保证删除 Redis 和更新数据库这两个操作的原子性,所以这个过程如果有其他线程来访问,还是会存在数据不一致问题。所以,如果需要在极端情况下仍然保证 Redis 和 MySQL 的数据一致性,就只能采用最终一致性方案。比如基于 RocketMQ 的可靠性消息通信,来实现最终一致性。要严格保证数据库和redis数据一致,可使用内存队列,但是比较消耗吞吐量。

你可能感兴趣的:(Redis,数据库,redis,java)