当前位置: 首页 > news >正文

Redis从库读取主库创建且已过期的key

在 Redis 主从复制架构中,从库在读取一个主库创建且已过期但尚未被删除的键时,其行为取决于 Redis 的版本

  1. Redis 3.2 之前(有问题的行为):

    • 从库会返回已过期的数据。 这是因为:
      • 主库负责管理过期键。过期键的删除(无论是惰性删除还是定期删除)在主库上触发。
      • 当主库删除一个过期键时,它会向所有从库发送一个 DEL 命令,从库才会删除该键。
      • 关键点: 如果主库尚未执行删除操作(例如,该键刚过期,还没来得及被惰性删除或定期删除扫描到),那么这个过期的键及其值仍然存在于从库的内存中。
      • 从库的视角: 从库不会主动检查键是否过期。它只忠实地保存和执行来自主库的复制流中的命令。如果主库没有发送 DEL 命令,从库就认为这个键仍然有效。
      • 结果: 客户端连接到一个从库,请求这个过期的键,从库会直接返回键的值,就像它没有过期一样。这导致了读取到过期数据的不一致性问题。
  2. Redis 3.2 及之后(修复的行为 - 逻辑过期时间):

    • 从库会返回 nil (或者等效的空结果,如空列表/集合等)。 Redis 3.2 引入了一个重要的改进来解决这个问题:
      • 主库在向从库同步带有过期时间(EXPIRE/PEXPIRE/SET ... EX 等)的键时,不再同步绝对过期时间戳,而是同步逻辑过期时间(相对时间)。
      • 具体来说,主库同步的是 PEXPIREAT 命令,但参数被转换成了键的剩余生存时间(TTL)的毫秒数。例如,主库不是发送 PEXPIREAT mykey 1718541235000(绝对时间戳),而是计算这个绝对时间戳与当前时间的差值,发送 PEXPIRE mykey 5000(表示还剩 5000 毫秒过期)。
    • 关键点: 从库接收到 PEXPIRE mykey <ttl> 命令后,会在本地重新计算这个键的绝对过期时间戳(基于从库自身的本地时钟加上收到的 <ttl>)。
    • 结果:
      • 当客户端在从库上读取一个键时,从库会使用自己本地存储的绝对过期时间戳来检查键是否过期。
      • 如果从库判断该键已经过期(根据它自己计算出的绝对时间戳),它会在返回结果之前,将该键视为不存在,从而返回 nil
      • 同时,从库不会主动删除这个键。它只会在读取时判断并返回空结果。实际的删除仍然需要等待:
        • 主库的惰性删除或定期删除触发,然后主库发送 DEL 命令到从库。
        • 或者,当该键在从库上被读取时(触发从库的惰性删除逻辑),从库会删除它并返回 nil。但删除操作不会被传播回主库或其他从库。

总结:

Redis 版本从库读取主库创建且已过期但未删除的键原因
< 3.2返回键的值 (过期数据)从库不检查过期,依赖主库发送 DEL 命令删除。主库未删,从库数据仍在。
>= 3.2返回 nil (或等效空结果)主库同步相对TTL,从库基于自身时钟计算绝对过期时间戳并在读取时检查。如果过期则视作不存在。

重要补充说明:

  1. 主库删除是最终来源: 即使 Redis >= 3.2 的从库在读取时返回了 nil,这个过期的键仍然物理存在于从库内存中,直到主库真正执行删除并同步 DEL 命令,或者该键在从库上被访问触发了惰性删除。
  2. 主从延迟: 在主从复制存在延迟的情况下,主库删除键后发送 DEL 命令到达从库之前,从库可能已经根据本地计算的过期时间戳返回了 nil(>=3.2)或者还在返回过期数据(❤️.2)。复制延迟会加剧短暂的不一致窗口期。
  3. 从库的惰性删除: 当客户端在 Redis >= 3.2 的从库上读取一个它认为已过期的键时,它不仅返回 nil,还会在执行读取操作后,在内部删除这个键(惰性删除)。这是从库本地清理过期键的一种方式。
  4. 一致性考虑: Redis 主从复制默认是最终一致性的。在过期键的处理上,尤其是在存在复制延迟时,不能保证在所有节点上严格同时过期并被删除。Redis 3.2+ 的改进极大地减少了读取到过期数据的可能性,但物理删除的传播仍然依赖主库的删除操作和复制流。

因此,对于现代 Redis 部署(>=3.2),你可以放心,从库在读取一个主库创建且已过期的键时,会返回 nil,避免了返回陈旧数据。 如果你使用的是旧版本,则存在返回过期数据的风险。

相关文章:

  • 断言(Assertion)中常用的正则表达式
  • 《汇编语言:基于X86处理器》第2章 x86处理器架构
  • Neo4j 入门到精通(Cypher语言详解)
  • 第 1 章,[标签 Win32] :第一个 WIn32 程序,头文件
  • pthread_once函数使用场景与原理
  • 设计模式精讲 Day 5:原型模式(Prototype Pattern)
  • NAT 与代理服务器 -- NAT,NAPT,正向代理,反向代理
  • 强化学习之 DQN、Double DQN、PPO
  • 黑马python(八)
  • springboot使用nacos注册中心、配置中心的例子
  • AndroidView的简单使用
  • 物制药自动化新突破:EtherNet/IP转Modbus TCP网关模块实战应用
  • 【AI Study】第四天,Pandas(6)- 性能优化
  • 系统思考与核心竞争力
  • 【AI论文】ReasonMed:一个370K的多智能体生成数据集,用于推进医疗推理
  • OpenStack 入门体验
  • wireshark过滤器的使用
  • 21.加密系统函数
  • 海豚人工智能与大数据实验室的指导和系统内的指导文件是不一样的​
  • Pandas 中的 Period 对象
  • 网站制作常见问题 图片版权/市场营销策划书
  • 深圳物流公司电话号码/seo推广营销公司
  • 澳环网站设计/如何制作网站教程
  • 东莞定制网站建设/什么是seo如何进行seo
  • 最好记得网站域名/河北关键词seo排名
  • 云南建筑培训网/seo外链推广工具