千锋教育-做有情怀、有良心、有品质的职业教育机构

手机站
千锋教育

千锋学习站 | 随时随地免费学

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

关注千锋学习站小程序
随时随地免费学习课程

当前位置:首页  >  应聘面试  >  Java面试题  > 如何保证Redis缓存与数据库的同步?你确定不来看看这道高频面试题

如何保证Redis缓存与数据库的同步?你确定不来看看这道高频面试题

来源:千锋教育
发布人:syq
时间: 2022-10-11 17:24:06 1665480246

  今天小千要给大家分享一道关于数据库缓存同步的面试题,希望通过这道面试题可以帮助大家搞定面试官。

如何保证Redis缓存与数据库的同步

  一. 数据缓存

  数据缓存在高并发的系统设计中很常见,因为Redis确实能有效地解决数据库和磁盘的I/O瓶颈,当一个高并发接口要查询低频修改的数据时,我们都建议用Redis实现数据缓存。

  一般的缓存实现思路如下:

50 (1)

  其实缓存的实现思路很简单,这个思路能保证只有第一次查询的是数据库,后续的访问查询的都是Redis,这样不仅提高了接口的访问效率,还在一定程度上实现了数据库的读写分离。

  那么现在问题来了,如果我们的数据库数据发生了变化,Redis怎么保证和数据库里的数据一致呢?这个问题就是我们今天要探讨的缓存同步问题。

  二. 缓存同步分析

  缓存同步这个思路相信大家很快就能搞清楚,大概思路如下:

51 (1)

  当我们对业务库做了修改,我们可以通过同步更新的方式去同步,也可以通过暴力删除Redis的方式去同步。因为删除Redis,会再次查询数据库的最新数据,这样就可以达成同步的目的。但不管你使用哪种方式,都会存在一些意想不到的问题,如下:

52 (1)

  先写数据库,再更新Redis,上图中演示了一种极端情况,按照时间轴的发展,数据库里的最新值是8,但Redis中的最新值是9,并没有一致。

53 (1)

  如果我们先更新Redis,再写数据库,按照时间轴,Redis里的最新值是8 ,数据库里的最新值是9,还是没有保持一致。

54 (1)

  先写数据库,再删Redis,这也不行。

  如上图,当数据库里的值为9,然后再删Redis。假如这时有一个读线程来了,发现Redis数据没了,这个读线程立即查询数据库,读到的就是9。然而不巧的是另外一个写线程将数据库改为8 ,也就是说数据库最新为8,结果缓存发生在更新数据库之后,缓存最新的值就是9,还是不能一致。

55 (1)

  如果我们先删Redis再写数据库,写线程上来把Redis删了,读线程立即读数据库,比如读到的旧数据是8,然后写线程再改数据库为9,这时数据库最新为9,但Redis中的值是8,结果还是不一致。

  三. 缓存同步解决思路

  上面分析了四种情况,它们在极端情况下都不能保证数据库和Redis的双写一致性,那到底为什么不能呢?问题到底出在哪里了,其实原因很简单,就是我们不能保证数据库和redis操作的原子性!在我们进行这两个操作时,总是有别的线程在破坏数据,所以才会出现各种问题,那怎么解决呢?我们先来看看下面的解决思路:

56 (1)

  这个思路大致是这样的,写线程只负责改数据库,不要去参与Redis同步的问题,Redis同步交给一个严格顺序的pipeline解决。这个pipeline的流程是,当数据库发生数据变化会立即产生binlog日志,我们可以借助阿里的canal组件去监听binlog,同时解析binlog,将解析的结果以消息的方式发送给MQ。MQ要保证严格顺序,再通过消费者去消费消息,将最新的数据覆盖更新到Redis,到此就能解决缓存的同步。

  现在你对数据库和Redis缓存的同步问题还有疑惑吗?如果还有别的问题,请关注我们吧,干货不断哦。

tags:
声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。
10年以上业内强师集结,手把手带你蜕变精英
请您保持通讯畅通,专属学习老师24小时内将与您1V1沟通
免费领取
今日已有369人领取成功
刘同学 138****2860 刚刚成功领取
王同学 131****2015 刚刚成功领取
张同学 133****4652 刚刚成功领取
李同学 135****8607 刚刚成功领取
杨同学 132****5667 刚刚成功领取
岳同学 134****6652 刚刚成功领取
梁同学 157****2950 刚刚成功领取
刘同学 189****1015 刚刚成功领取
张同学 155****4678 刚刚成功领取
邹同学 139****2907 刚刚成功领取
董同学 138****2867 刚刚成功领取
周同学 136****3602 刚刚成功领取
相关推荐HOT