每日面试题:redis做为缓存,mysql如何与redis进行同步?

redis做为缓存,mysql如何与redis进行同步(双写一致性)

双写一致:

当修改了数据库的数据也要同时更新缓存的数据,缓存和数据库的数据要保持一致

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

写操作: 延迟双删(有两种情况:1.先删除缓存,再跟更新数据库。 这种方法可能会造成脏数据。比如有两个线程,线程一来了先删除缓存,线程二来了 查询缓存后发现没有数据,就回去数据库里读,读到一个不一样的数据 然后放入缓存 线程一更新数据库 就导致缓存数据库不一致了。

2 先操作数据库 后删除缓存:

更新数据库 为一个不同的值 然后再删除缓存 另一个线程 查数据 发现缓存没有 就去把数据库的数据拿到缓存中 这样就没有问题了 。

但是还有一种情况 线程查缓存的时候 刚好过期了 线程就拿到数据库的数据 但是没有同步到缓存之前 另一个线程 更新数据库了 然后删除缓存 然后回到线程1 线程1 要去写入缓存 就会把之前没有更新的数据写入 这样就会导致 脏数据 但是 这种情况很少见

这两种情况 都不太行 所以我们要进行双删 还要延时 当修改数据库之后 等一会再次删除缓存 这样就能极大避免脏数据 但还是不能完全避免 。

非要保持强一致性 怎么办呢?

像那些存入缓存中的数据 都是 读多写少 所以 我们可以上一个读写锁 1 共享锁:读锁readLock,加锁之后,其他线程可以共享读操作 2 排他锁:独占锁 writeLock 也叫写锁,加锁之后,阻塞其他线程读写操作 ,在写数据时,添加,能堵塞其他进程的读写

这是读锁代码实现

这是写锁代码实现

使用读写锁 能保证强一致 性能低 (大多数要进行强一致去用)

最常用的 还是图下 用MQ的异步通知 这个我后面会说


 

那我们关于这道面试题怎么回答呢?

1 介绍自己的业务,我当时是把文章的热点数据存入缓存,因为实时性没有那么高,所以当时采用的是异步的方案去同步数据

2 如商城系统,我当时是把一些库存存到了缓存中,需要进行实时同步,要保证强一致性,所以当时采用是redisson提供的读写锁来保证数据的同步。

如果面试官继续发问:那你来介绍一下异步和同步的方案

我:

我们一般允许延时一致的业务,采用异步通知, 我使用了MQ中间件,更新数据之后 通知缓存去删除

我们要强一致性的,采用Redisson提供的读写锁

1 共享锁:独锁readLock,加锁之后,其他线程可以共享读操作

2 排他锁:独占锁writeLock也叫写锁,加锁之后,阻塞其他线程的读写操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值