Redis作为缓存,MySQL的数据又该怎么和Redis进行同步呢?

Redis作为缓存,MySQL的数据该怎么和Redis进行同步呢?

这是我们请求数据,redis和DB之间的常见关系图。

双写一致的意思是什么呢?

其实双写一致性就是指当修改了数据库的数据之后,也要同时更新缓存的数据,缓存和数据库的数据要保持一致。

在上图中,读操作:缓存命中,直接返回;缓存未命中,就查询数据库,写入缓存,设定超时的时间

写操作:延迟双删

延迟双删的流程图如下:

无论是先修改数据库还是先修改缓存,都是错误的,都会出问题。

肯定有人会疑惑,为什么要删除两次缓存呢?

删除两次缓存是为了降低脏数据的出现,因为无论先操作redis还是DB,都会出现脏数据,最后缓存和数据库的结果可能并不一致,所以要进行一个延迟双删。并且读的速度是大于写的速度的,也就是说在修改数据库之前,redis可能就已经把脏读的数据写进去了,这个时候数据库完成修改之后,再进行一次删除缓存,将脏数据删掉,在下个线程时,就会重新构建缓存。

延时:为的是修改数据库之后,将主节点的数据同步到从节点之中。

我们也可以用到其他操作来进行redis和mysql的同步,也有两种方案,根据业务来决定。

一、异步方案 : 列如我在我的项目中将短链接中的热点数据存入到了缓存之中,这边的热点数据虽然是热门,但是其对实时要求性并不是很高,所以我采用了异步的方案同步的数据。

介绍: 允许延时一致的业务,采用异步通知,保证数据的最终的一致性。

  1. 可以使用MQ中间件来完成数据的同步,在Mysql的数据更新之后,发送消息通知给MQ,缓存服务来接收消息,然后将数据同步更新到缓存之中。

##要保证MQ的可靠性

  1. 利用阿里自制的canal中间件,不需要修改业务代码,因为它是伪装成了mysql的一个从节点,canal通过读取binlog之中的数据来更新缓存内容。

##canal是基于mysql的主从同步来实现的。Binlog中记录了DDL和DML语句(数据定义语言和数据操纵语言),但是并不包括数据查询语句(select,show)

二、redisson读写锁 : 例如我在项目中实现了一个抢券的行为,将抢券的库存,存入到了缓存之中,这个需要实时的来进行数据同步,为了保证数据的强一致性,就可以采用redisson提供的读写锁来保证数据的同步。

介绍: 强一致性的,采用Redisson提供的读写锁

1.共享锁: 读锁readLock,在开启读锁之后,其他线程可以共享它的读操作。

2.排他锁: 也叫独占锁writelock,在开启了排他锁之后,阻塞其他线程进行读写的操作。

但是读写锁的这种方法,虽然能保持强一致,但是性能低

排他锁是怎么保证读写,读读互斥的呢?

排他锁的底层原理也是使用了setnx,保证了同时只有一个线程操作锁住的方法,让其他线程无法调用。

延迟双删又是什么呢?

延迟双删中,如果是写操作,我们要先将缓存的内容删掉,再更新数据库,最后再延时来进行缓存的删除。这个延时所代表的时间多久并不好确定,在延时的过程中可能还会出现脏数据,并不能保持数据的强一致性,所以不用。

至于双写一致性,就是mysql的数据与redis的数据进行同步,在绝大多数场景,我们都可以直接使用阿里的canal组件来实现数据同步,不需要更改我们的业务代码,只需要部署canal服务,当mysql更新之后,canal会读取binlog服务,然后再通过canal的客户端获取数据,再更新缓存就可以了。

##加锁了之后,才能保证强一致性,延迟双删和异步通知都是不加锁的,所以无法保证强一致性。
  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值