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

400-811-9990
手机站
千锋教育

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

千锋教育

扫一扫进入千锋手机站

领取全套视频
千锋教育

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

上海
  • 北京
  • 郑州
  • 武汉
  • 成都
  • 西安
  • 沈阳
  • 广州
  • 南京
  • 深圳
  • 大连
  • 青岛
  • 杭州
  • 重庆
当前位置:南京千锋IT培训  >  技术干货  >  怎么保证Redis与数据库的缓存同步?

怎么保证Redis与数据库的缓存同步?

来源:千锋教育
发布人:wjy
时间: 2023-03-01 17:04:45

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

  一. 数据缓存

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

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

怎么保证Redis与数据库的缓存同步437

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

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

  二. 缓存同步分析

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

怎么保证Redis与数据库的缓存同步913

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

怎么保证Redis与数据库的缓存同步1315

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

怎么保证Redis与数据库的缓存同步1670

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

怎么保证Redis与数据库的缓存同步2016

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

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

怎么保证Redis与数据库的缓存同步2458

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

  三. 缓存同步解决思路

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

怎么保证Redis与数据库的缓存同步3001

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

声明:本站稿件版权均属千锋教育所有,未经许可不得擅自转载。

猜你喜欢LIKE

三元运算符是什么?三元运算符怎么用

2023-06-20

Java常量是什么?

2023-06-14

保证Servlet线程安全的方法有哪些?

2023-06-05

最新文章NEW

什么是javascript?

2023-06-12

javascript常用正则

2023-04-20

用c语言编写爱心的代码

2023-04-14

相关推荐HOT

更多>>

快速通道 更多>>

最新开班信息 更多>>

网友热搜 更多>>