MySQL和Redis数据一致性

MySQL和Redis数据一致性

1.什么是双写一致性?

当我们更新了数据库的数据之后,同时保证redis的数据库同时更新。

2.数据读取的过程

当有请求读取数据库的时候,首先从缓存中读取,如果命中缓存直接返回数据,如果没有命中缓存,则从数据中查询数据,然后将查询的数据写入缓存,之后返回查询后的数据。

3.保证双写一致性的策略:
  • 先更新缓存,再更新数据库
  • 先更新数据库,再更新缓存
  • 先删除缓存,再更新数据库
  • 先更新数据库,再删缓存
  • 异步更新缓存

1.先更新缓存,再更新数据库

如果更新缓存成功,更新数据库失败,会造成缓存的脏数据

2.先更新数据库,再更新缓存

缺点: 在高并发的情况下,比如: 线程A更新的数据由于网络或者其他原因,在线程A还没有来得及更新缓存的时候,线程B更新了数据库,并且更新了缓存,接着线程A才更新缓存,就会导致线程B对缓存的更新丢失。

3.先删除缓存,在更新数据库

方法3解决了方法2中缓存丢失的情况,但是在高并发的情况下,依然会存在不一致的情况,例如:线程A做写操作,首先删除缓存然后准备更新数据库,这时候线程B执行了读操作,发现缓存没有命中,所以从数据库读取,这时候读取的是旧值,并且线程B会将旧值写入缓存,接着线程A完成了数据库的更新,此时造成数据库和缓存的出现了数据不一致的现象。

解决思路: 延时双删

只要在线程A完成数据库更新之后,稍作一些延迟,然后再删除缓存(这一次延迟时间一定要大于业务的一次读操作需要到的时间)

步骤:

1)、先删除缓存

2)、再写数据库

3)、休眠**(休眠时间由自己项目读数据业务逻辑的耗时时间确定,一般大于即可,因为需要确保读请求结束,写请求可以删除读请求造成的缓存脏数据)**

4)、再删除缓存

**问题:**如果双删失败了如何解决?

1.设置缓存过期时间

将所有的写操作都以数据库为标准,只要达到缓存过期时间,则后面的读请求会从数据库中读取然后回填到缓存。

解决数据不一致的: 双删策略 + 缓存超时设置

存在的弊端: 结合双删策略 + 缓存超时设置,可能会造成在超时时间内数据存在不一致性,这时又增加了写请求的消耗。

4.先更新数据库,在删缓存

在高并发的情况下会造成数据库和缓存不一致的现象,比如: 线程A查询数据,正准备将数据写入缓存的时候,线程B更新了数据库,然后执行了删除缓存的操作,这时线程A才把之前读取的旧值写入到缓存。但是该现象出现的概率比较低,因为写操作的时间大概率是比读操作长的,所以一般不会出现在一次读操作期间进行了一次写操作。

解决思路: 使用时延,延迟双删策略,如果删除缓存失败,那就需要不断的循环删除,删除失败后,可以将要删除的key放入到队列中,然后重复尝试删除知道删除成功。

5.异步更新缓存(基于订阅binlog的同步机制)

思路: Mysql binlog增量订阅消费 + 消息队列 + 增量数据更新到Redis

数据库的更新操作完成后不直接操作缓存,而是把这个操作命令封装成消息扔到消息队列中,然后由Redis自己去消费更新数据,消息队列可以保证数据操作顺序一致性,确保缓存系统的数据正常。

参考资料:
MySQL和Redis数据一致性:.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值