第9章 数据库

追踪redisServer.db、redisDb.dict与expires完成键空间、TTL、惰性和定期删除以及通知 覆盖9个正式节点,并以Redis 3.0源码、故障和恢复对账验收。

学习目标

  • 能画出键空间与过期字典的关系
  • 能解释惰性与定期删除的协作
  • 能说明键空间通知的工作方式

为什么从“键空间与TTL时钟台”开始

第9章 数据库的核心任务是追踪redisServer.db、redisDb.dict与expires完成键空间、TTL、惰性和定期删除以及通知。命令返回值只暴露外层合同;实现解释还必须连接内存结构、写入与读取路径、事件顺序以及失败后的旧状态回收。键空间与TTL时钟台把这些关系放进同一条可复位轨迹。

先写预测:当过期时点由“刚到期”进入“长期过期”时,哪个可观察状态最先变化?再规定什么结果会推翻当前解释。交互中的分数只表达透明因果方向,不冒充真实Redis测量。

来源、版次与独立重写边界

黄健宏作者读者服务页确认正式出版新版以Redis 3.0为源码基线,列出4部分、24章及完整小节,并链接Redis 3.0中文注释源码。本课程据此映射24个正式单元、145个目录节点,另设学习地图和总复习;未取得出版正文授权,目录只界定范围,不宣称复现原书正文。

本章字段与控制流由Redis官方3.0源码:db.c和作者注释源码交叉核对;Redis当前持久化文档只用于辨认版本差异。中文解释、图示、交互、实验与答案均为独立教学重写,不把目录页或代码仓库许可证误报为原书许可证。

本章术语与源码合同

第9章 数据库必须守住“键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致”。观察同时记录键空间与TTL时钟台一致率与触发路径分叉风险;只有结构快照、函数入口、运行结果和故障反例互相一致,才接受实现结论。

⚡ 数据库键空间与过期策略
键空间字典 + 过期字典(t=0红色键已过期;点击推进时间观察删除行为键空间(dict)user:1无 TTLsession:42TTL 8scart:7无 TTLtoken:abcTTL 3scounter无 TTL过期字典(expires)——只有带 TTL 的键在这里session:42 @ t=8token:abc @ t=3
惰性删除省 CPU 但可能堆积内存;定期删除(serverCron 每秒 10 次随机抽查)兜底。两者配合:惰性为主、定期为辅,在内存与算力间平衡。
操作日志
  1. 1.数据库由键空间字典 + 过期字典组成。带 TTL 的键登记在过期字典,到点后删除。

作者目录逐项深读

服务器中的数据库

四级证据 1/9。 redisServer保存数据库数组,redisDb至少连接键空间dict与expires字典;客户端db指针选择当前逻辑库。本节点用“服务器中的数据库”作观察点,执行rg 'expireIfNeeded|activeExpireCycle|propagateExpire' src/db.c src/server.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证服务器中的数据库时,先预测过期时点从“刚到期”切到“长期过期”会改变哪个字段、偏移、文件或消息;再固定触发路径做一次对照。若故障注入没有破坏“键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致”,就撤回当前解释而不是补写故事。

切换数据库

四级证据 2/9。 SELECT改变客户端指向的redisDb而不是搬迁键;新客户端默认使用编号0。本节点用“切换数据库”作观察点,执行rg 'expireIfNeeded|activeExpireCycle|propagateExpire' src/db.c src/server.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证切换数据库时,先预测过期时点从“刚到期”切到“长期过期”会改变哪个字段、偏移、文件或消息;再固定触发路径做一次对照。若故障注入没有破坏“键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致”,就撤回当前解释而不是补写故事。

数据库键空间

四级证据 3/9。 键空间操作除dict变更外还要维护过期、阻塞键、WATCH与通知等旁路状态。本节点用“数据库键空间”作观察点,执行rg 'expireIfNeeded|activeExpireCycle|propagateExpire' src/db.c src/server.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证数据库键空间时,先预测过期时点从“刚到期”切到“长期过期”会改变哪个字段、偏移、文件或消息;再固定触发路径做一次对照。若故障注入没有破坏“键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致”,就撤回当前解释而不是补写故事。

设置键的生存时间或过期时间

四级证据 4/9。 expires字典保存绝对毫秒时刻并与键空间共享键指针;TTL/PTTL把绝对时刻换算为剩余时间。本节点用“设置键的生存时间或过期时间”作观察点,执行rg 'expireIfNeeded|activeExpireCycle|propagateExpire' src/db.c src/server.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证设置键的生存时间或过期时间时,先预测过期时点从“刚到期”切到“长期过期”会改变哪个字段、偏移、文件或消息;再固定触发路径做一次对照。若故障注入没有破坏“键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致”,就撤回当前解释而不是补写故事。

过期键删除策略

四级证据 5/9。 定时删除耗CPU、惰性删除占内存,实际实现组合访问时检查与周期性抽样。本节点用“过期键删除策略”作观察点,执行rg 'expireIfNeeded|activeExpireCycle|propagateExpire' src/db.c src/server.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证过期键删除策略时,先预测过期时点从“刚到期”切到“长期过期”会改变哪个字段、偏移、文件或消息;再固定触发路径做一次对照。若故障注入没有破坏“键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致”,就撤回当前解释而不是补写故事。

Redis的过期键删除策略

四级证据 6/9。 定时删除耗CPU、惰性删除占内存,实际实现组合访问时检查与周期性抽样。本节点用“Redis的过期键删除策略”作观察点,执行rg 'expireIfNeeded|activeExpireCycle|propagateExpire' src/db.c src/server.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证Redis的过期键删除策略时,先预测过期时点从“刚到期”切到“长期过期”会改变哪个字段、偏移、文件或消息;再固定触发路径做一次对照。若故障注入没有破坏“键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致”,就撤回当前解释而不是补写故事。

AOF、RDB和复制功能对过期键的处理

四级证据 7/9。 RDB载入按当前时间处理过期,AOF可传播DEL;副本服从主节点传播,避免各节点独立时钟造成分叉。本节点用“服务器中的数据库”作观察点,执行rg 'expireIfNeeded|activeExpireCycle|propagateExpire' src/db.c src/server.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证AOF、RDB和复制功能对过期键的处理时,先预测过期时点从“刚到期”切到“长期过期”会改变哪个字段、偏移、文件或消息;再固定触发路径做一次对照。若故障注入没有破坏“键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致”,就撤回当前解释而不是补写故事。

数据库通知

四级证据 8/9。 键空间通知把事件类型与键名发布到约定频道,是否启用和事件类别由配置控制,消息不承担持久队列语义。本节点用“切换数据库”作观察点,执行rg 'expireIfNeeded|activeExpireCycle|propagateExpire' src/db.c src/server.c或等价源码探针,保存版本、输入、前后状态和能推翻解释的反例。

验证数据库通知时,先预测过期时点从“刚到期”切到“长期过期”会改变哪个字段、偏移、文件或消息;再固定触发路径做一次对照。若故障注入没有破坏“键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致”,就撤回当前解释而不是补写故事。

重点回顾

四级证据 9/9。 第9章 数据库的回顾要重新证明“键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致”,并用同一输入比较结构前态、变更轨迹、故障首错与恢复后态

验证重点回顾时,先预测过期时点从“刚到期”切到“长期过期”会改变哪个字段、偏移、文件或消息;再固定触发路径做一次对照。若故障注入没有破坏“键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致”,就撤回当前解释而不是补写故事。

最小源码与运行切片

+git clone --branch 3.0 --depth 1 https://github.com/redis/redis.git redis-3.0
+cd redis-3.0
+rg 'expireIfNeeded|activeExpireCycle|propagateExpire' src/db.c src/server.c

该切片固定Redis 3.0分支、编译器、配置、数据集和命令序列;先保存结构或函数位置,再运行隔离实例。任何持久化损坏、断线、故障转移、大键或高流量实验都必须使用临时数据并规定CPU、内存、磁盘、延迟和停止上限。

unit: rdi-09-database
source_file: db.c
axis_a: "过期时点"
axis_b: "触发路径"
fault: "只从主键字典删除过期键,或让从节点自行产生与主节点不同的过期决议"
invariant: "键空间和过期字典引用同一键,过期语义在命令、RDB、AOF和复制路径中一致"
replay: same_version_same_input

三个必须主动触发的误区

误区 1

现象 → 全库统一 TTL 原因 → 同时过期形成雪崩 修法 → TTL 加随机抖动错峰

误区 2

现象 → 切换数据库不验证 原因 → 写错逻辑库污染数据 修法 → SELECT 后立即确认 dbindex

误区 3

现象 → 键空间通知乱订阅 原因 → 通知流量放大负载 修法 → 只订必要事件并评估成本

小结

  • 服务器默认 16 个逻辑数据库
  • 键空间由字典承载
  • 过期字典记录生存时间
  • 惰性加定期删除过期键
  • 通知机制广播键空间事件

练习、答案与节点验证

练习

问题 1: 过期键为什么用惰性加定期两种删除?

问题 2: 大量键同时过期会发生什么?

问题 3: 设计一个缓存预热方案,避免整批键同一时刻过期。(独立实现)

术语复核与本章回顾

完成第9章 数据库意味着能从db.c解释追踪redisServer.db、redisDb.dict与expires完成键空间、TTL、惰性和定期删除以及通知,能运行章专属状态实验,能制造反例并在复位后证明旧状态没有残留。

资料与写作方式声明

本章以黄健宏《Redis设计与实现》(机械工业出版社)权威目录界定学习范围,并结合正文列出的技术资料独立重写;不宣称复现原书正文,也不沿用原作表述。

原作版权归作者与出版社所有;本站原创教学结构与表述仅供学习交流。

讨论

评论区加载中…