面试记录-怎么保证redis和mysql的一致性;

这个问题是个常见的面试题,面试官主要考察的还是一个并发下的安全问题

首先这个问题的答案是,redis和mysql作为两种不同的存储介质,我们的业务需要做到的是保证两者的最终一致性。

一般我们引入redis是为了查询的时候提高效率,所以我们在查询的时候先查询redis,如果redis中有数据,直接返回给用户,如果没有数据,查询mysql然后回写到redis,这是使用缓存后正常的一个查询流程

但是在进行修改的时候,通常有两种方式:

1、先修改mysql中的数据,然后再删除缓存,等下个线程查询的时候发现缓存没有数据,再次查询回写

这个方案在不考虑特殊情况下可以保证数据的最终一致性,但是在并发的情况下,在第二步删除redis的操作没有完成时,有另外的线程进来查询数据,那么查询到的就是旧的数据,但是优点是只需要删除一次缓存的数据

2、先删除缓存,然后更新mysql,等待一段时间(这个时间要保证mysql数据更新完成)再次删除缓存,这种方案叫做延时双删

延时双删也是可以保证数据的最终一致性的,但是在整个事务执行的过程中,如果在并发情况下,有其他线程在第二步没有更新完mysql之前进行查询,那么查询到的依然是旧的数据,并且在更新mysql之后也要保证等待的时间要在mysql更新之后,最后再次删除redis中的数据

所以我们通常在不考虑特殊情况下,要保证redis和mysql数据最终一致性,用到方案1就OK。

拓展,如果要考虑特殊情况,比如mysql数据在向redis同步的时候reids宕机了,那么可以使用MQ进行消息投递,因为MQ有消息失败重试机制,此外还有第三种方案就是使用阿里的组件Cnanal监控mysql的binlog日志进行异步的推送

无论是使用MQ还是Cannal我个人都不推荐,在业务链路上添加越多的技术点,伴随的风险点就越多!!!

此外,如果在特殊的场景下,比如下单后扣减库存等特殊的场景,那么需要做的就是将mysql和redis的修改操作当做同一事物进行加锁,以达到数据最终一致性。但是普通的业务场景不推荐这么做,因为使用缓存的目的就是为了提高系统的吞吐量,这种操作有点儿南辕北辙的意思。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值