关于redis:搞定面试官系列当面试官问你如何保证缓存和数据库双写一致性时他到底想问什么

64次阅读

共计 2007 个字符,预计需要花费 6 分钟才能阅读完成。

面试开始

小伙子你好,看你简历上写到了 MySQL 和 Redis。明天咱们就围绕他们两个开展吧。Redis 和 MySQL 是后端开发中举重若轻的重要角色。理论开发中二者也基本上如影随行,为了进步性能和响应,Redis 经常寄存热点数据,MySQL 寄存所有数据,保证数据长久化。所以 Redis 能够说是 MySQL 的一部分数据。

那么问题来了,当 MySQL 中的长久化数据产生扭转,如何告诉 Redis 呢?也即如何保障缓存和数据库数据的双写一致性呢?


面试官您好,咱们在开发中采取的计划是:先更新数据库,而后删除相应缓存,直到下次申请缓存发现没有数据,再从 MySQL 中读取,同时将数据更新到 Redis

那为什么采纳删除缓存而不是更新缓存呢?


如下图所示,如果采取更新缓存的形式,可能 呈现申请 A 先于申请 B 产生,更新缓存应该比申请 B 更新缓存早才对,然而因为网络等起因,B 却比 A 更早更新了缓存,这就导致了脏数据

其次,如果你是一个写数据库场景比拟多,而读数据场景比拟少的业务需要,采纳更新缓存的计划就会 导致数据压根还没被读取过,但缓存已被频繁的更新,节约性能。

那先删除缓存,再更新数据库会不会有什么问题?


如下图所示,申请 A 进行写操作,删除缓存,申请 B 查问发现缓存不存在,就去数据库查问失去旧值,之后将旧值写入缓存,此时申请 A 再将新值写入数据库。
这种状况就会导致 数据不统一 的情景呈现。而且,如果不采纳给缓存设置过期工夫策略,该缓存数据永远都是脏数据。

好的,刚刚说的计划的确在并发环境中都会有问题。那你们采纳先更新数据库,再删除缓存,这种计划肯定不会呈现并发问题吗?


答案是 不肯定,也可能会呈现并发问题 。如下图所示,
当步骤 Step3 的更新数据库操作比步骤 Step2 的读取数据库操作耗时更短,就有可能使得步骤 Step4 先于步骤 Step5,此时缓存中的就是脏数据。但个别状况下 数据库的读操作的速度是远快于写操作的(此点从 MySQL 的并发读写量就可看出,雷同硬件配置下并发读的效率是并发写的数倍)

因而,如果你想实现根底的缓存和数据库双写统一的逻辑,那么在大多数状况下,在不想做过多设计、减少太大工作量的状况下,请 先更新数据库,再删除缓存!

先更新数据库,再删除缓存,除了你刚刚说得问题,还会有别的问题吗?


如果MySQL 采纳了读写拆散架构,当申请 A 更新数据在 master 库上并删除了缓存,但此时数据库主从同步还未实现。申请 B 查问缓存产生 Cache miss 之后从 slave 库上读取到的还是旧值,此时也会造成数据不统一。

你刚刚说到先更新数据库,再删除缓存也有可能造成数据不统一,怎么解决呢?


采纳 延时双删 。如下图所示,申请 A 更新数据库之后,为避免删除缓存后行产生于申请 B 的将缓存写入旧值,能够通过将申请 A 更新完数据库之后休眠一会(例如 100ms,200ms,依据理论业务场景拟定),再删除缓存,这样根本能保障缓存中寄存的不会是脏数据。主从架构也是这个原理,就是申请 A 在更新 master 之后不必立刻删除缓存,通过 延时双删保障主从同步曾经实现,最初删除缓存数据。

但你这种计划,申请 A 休眠一段时间的话,可能会影响到接口的 RT,升高零碎的吞吐量,如何解决呢?


这里比拟优雅的计划是通过 异步 实现。即开启一个线程池,在申请 A 的时候开启一个独自的线程,异步的休眠一段时间而后执行缓存删除。当然也能够通过将缓存中相应的 key 扔到音讯队列,通过 MQ 异步删除,但仅为了异步删除缓存就多加了一层音讯队列,可能会造成零碎设计更加简单,并且会带来别的问题。

后面始终有提到删除缓存,如果删除缓存失败了怎么办呢?


再加一个 重试机制,保障删除缓存胜利。

如果我肯定要数据库和缓存数据一致性怎么办?


没有方法做到相对的一致性,这是由 CAP 实践决定的,缓存零碎实用的场景就是非强一致性的场景,所以它属于 CAP 中的 AP。

CAP 实践是分布式系统中的经典实践,即一致性(Consistency)、可用性(Availability)、分区容错性(Partition tolerance)。

依据 BASE(Basically Available,Soft State 和 Eventually Consistent)实践,缓存和数据库只能做到数据的 最终一致性

面试完结

工夫也不早了,明天就到这里吧,看进去小伙子对这块把握的比拟深刻。咱们公司就短少你这种人才,要不当初就签把 Offer 签了吧。
这个时候你必定欲绝还迎,一手接 Offer 一边摆摆手:不行不行,深圳马那边也急着等我给回复呢,催了我好几天了。
面试官一听,payroll 组何在,加价!

小结

应用缓存并不是一个很简略的事件,尤其在须要缓存与数据库放弃强统一的场景,才晓得让数据库数据和缓存数据放弃一致性是一门很浅近的学识。
从远古的硬件缓存,操作系统缓存开始,缓存就是一门独特的学识。这个问题也被业界探讨了十分久,争执至今也无果,因为其实这是一个衡量的问题。
我是少侠露飞,爱技术,爱分享。

正文完
 0