【Redis进阶】缓存一致性问题

打印 上一主题 下一主题

主题 870|帖子 870|积分 2610

目次
缓存一致性问题概念
缓存一致性问题的成因
缓存一致性问题的解决方案
旁路设计模式中同步删除
焦点流程
存在问题 
耽误双删(口试常问)
焦点流程
耽误双删策略重要分为以下几个步调:
 耽误双删的应用场景
长处:
缺点:
监听binlog删除+重试(常用)
焦点流程
监听 Binlog 并删除缓存的流程
长处:
缺点:


缓存一致性问题概念

缓存一致性问题指的是缓存中的数据和数据库中的数据不一致的情况,这在分布式系统中尤其常见。缓存一致性问题可能导致用户读取到旧数据或者错误数据,从而影响系统的可靠性和用户体验.
缓存一致性问题的成因


  • 缓存更新不及时

    • 当数据库中的数据发生变化后,假如缓存中的数据没有及时更新,缓存和数据库的数据就会不一致。

  • 缓存与数据库更新的序次问题

    • 在举行数据写操作时,假如先更新数据库再更新缓存,或者先更新缓存再更新数据库,都有可能导致在并发情况下出现数据不一致的问题。

  • 分布式系统的并发问题

    • 在分布式系统中,多个节点可能同时读取和写入同一条数据,导致差别节点缓存的数据与数据库中的数据不一致。

  • 缓存淘汰策略

    • 缓存中存储的数据偶然会因为设置的逾期时间或内存空间不足而被淘汰。假如被淘汰的数据还没有逾期或者没有重新加载,就可能导致数据不一致。

缓存一致性问题的解决方案

旁路设计模式中同步删除

焦点流程


存在问题 

如图所示,更新请求进来,先更新数据,再删除缓存。但是会导致以下问题

  • 假如删除缓存失败,会导致脏数据
  • 在并发场景下,会导致数据不一致问题
写线程A读线程B
删除缓存
读取缓存,未命中,查询数据S1
更新请求进来,更新数据库S1->S2
删除缓存
将S1放入缓存
在上图所示:


  • 读线程B读取缓存,缓存中不存在,去查询数据库,查询到S1
  • 写线程A更新请求进来,更新数据库S1->S2,然后删除了缓存
  • 读线程B将S1放入缓存中。
  • 导致了数据库数据为S2,缓存中数据为S1. 
耽误双删(口试常问)

焦点流程


耽误双删策略重要分为以下几个步调:


  • 更新数据库

    • 首先,应用程序更新数据库中的数据。此时,缓存中的数据可能仍然是旧的。

  • 第一次删除缓存

    • 紧接着,删除缓存中与数据库中更新的数据对应的缓存条目。此操作确保下次读取数据时会从数据库中读取最新数据。

  • 耽误一段时间

    • 设置一个公道的耽误时间。这个耽误时间通常是根据系统的详细需求和网络耽误、数据库响应时间等因素来确定的。目的是等待所有可能的并发读请求完成。

  • 第二次删除缓存

    • 在耽误时间竣事后,再次删除缓存中的数据。这一步是为了处理可能在第一次删除缓存与数据库更新之间发生的并发写入或读取操作。

  1. //延迟双删伪代码
  2.    public void updateData(String key, String newValue) {
  3.     // 1. 更新数据库中的数据
  4.     db.update(key, newValue);
  5.     // 2. 删除缓存中的旧数据
  6.     redis.del(key);
  7.     // 3. 延迟一段时间
  8.     try {
  9.         Thread.sleep(500); // 延迟500毫秒
  10.     } catch (InterruptedException e) {
  11.         e.printStackTrace();
  12.     }
  13.     // 4. 再次删除缓存(以防止并发问题)
  14.     redis.del(key);
  15. }
复制代码
 耽误双删的应用场景



  • 高并发场景

    • 在高并发环境下,多个线程可能同时读写同一数据。耽误双删可以减少因并发操作导致的缓存不一致问题。

  • 需要强一致性的场景

    • 假如业务逻辑要求缓存中的数据与数据库中的数据必须保持一致(即便耽误一点时间),耽误双删是一种有用的策略。

长处


  • 减少并发问题:通过耽误第二次删除缓存,低沉了在更新数据库和缓存期间发生的并发问题,从而提高了缓存和数据库的一致性。
  • 简单易实现:耽误双删的实现逻辑相对简单,只需在代码中加入一些耽误处理即可。
缺点


  • 耽误时间设置复杂:耽误时间的选择需要非常慎重。耽误时间太短可能无法解决并发问题,太长又可能影响系统性能。
  • 仍然存在短暂的不一致性:在第一次删除缓存与数据库更新之间,仍可能出现短暂的不一致性。
  • 多次删除操作开销:两次删除操作增加了缓存的开销,特殊是在高频读写的场景下,可能对缓存性能产生肯定影响。
监听binlog删除+重试(常用)

焦点流程


监听 Binlog 并删除缓存的流程


  • 开启 MySQL Binlog

    • 首先,确保 MySQL 的 Binlog 功能已经开启,并且配置了适当的 Binlog 格式(如 ROW 格式,能更精确地记录行级别的变化)。

  • 监听 Binlog 日志

    • 使用工具或程序(如 Debezium、Canal、Maxwell 等)监听 MySQL 的 Binlog 日志,及时捕捉数据库的变化变乱。

  • 剖析 Binlog 变乱

    • 剖析 Binlog 日志中的变乱,识别出需要处理的表和行级数据变动(如 INSERT、UPDATE、DELETE 操作)。

  • 推送消息到消息队列
  • 删除对应的缓存

    • 根据剖析出的变动信息,定位需要删除的缓存条目。通常是根据变动的主键或其他唯一键来确定缓存键。

  • 重试机制

    • 假如删除缓存操作失败(如由于网络问题或 Redis 服务不可用),应触发重试机制,确保缓存删除成功。

长处


  • 及时性强:通过监听 Binlog,可以及时捕捉数据库的变化并更新缓存,确保缓存数据的新鲜度和一致性。
  • 可靠性高:通过重试机制,即使缓存删除失败,也可以或许在重试后成功删除,确保系统的稳固性。
  • 适应性广:这种方式可以适用于各种数据库变动,不需要在应用程序层面增加复杂的逻辑。
缺点


  • 实现复杂度高:需要引入外部工具(如 Canal),并且剖析 Binlog 和维护重试机制的实现较为复杂。
  • 性能开销:监听 Binlog 并频繁操作缓存会增加系统的性能开销,尤其是在高并发环境下。
  • 耽误问题:只管 Binlog 监听具有及时性,但实际操作中可能会有少量耽误,尤其是在高负载下。
缓存一致性问题是分布式系统中的一个复杂问题,需要根据详细的业务需求和场景选择符合的解决方案。通过公道的缓存策略和一致性保证,可以有用提高系统的性能和可靠性。

 
 

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

怀念夏天

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表