07. KVStore 版本四 架构深度解析
kvstore 架构深度解析
1. Recovery 层(恢复)
核心逻辑: 它是系统启动时的第一道防线
- 流程:
open->load_snapshot(加载基准数据) ->replay_log(重放增量日志) - 设计原因:内存数据库必须在重启后恢复到宕机前的状态。先读快照是为了速度,后重放日志是为了数据完整性
- 关键函数:
kvstore_recover(): 总入口。kvstore_load_snapshot(): 从磁盘加载静态数据;kvstore_replay_log(): 逐条读取 WAL 并调用replay_put/del
2. Logging 层 (持久化/WAL)
核心逻辑:Write-Ahead Logging (WAL)。 在修改内存前,先写入磁盘。
- **设计原因:**磁盘顺序写远快于随机写。只要日志在,数据就不会丢。
- 关键函数:
kvstore_log_put() / kvstore_log_del():将操作序列化为二进制流并写入文件。kvstore_log_header():写入校验信息,防止文件损坏导致无法识别。
3. Execution 层(执行/原子性控制)
核心逻辑:它是 Public API 和内部实现之间的协调者
**设计原因:**所有的写操作(PUT/DEL)都必须经过统一的“漏斗”。 它负责:1. 检查状态机; 2. 调用 Logging 持久化; 3. 调用 Apply 修改内存。
关键函数:
kvstore_exec_write():整个项目的灵魂。它决定了一个操作是“先写日志再改内存”的原子过程。kvstore_state_allow():权限拦截,比如“正在恢复中”或“已损坏”时的拒绝写入。
4. Apply 层(内存映射)
核心逻辑:真正修改内存数据结构(B+ 树)的地方。
- **设计原因:**区分
internal和普通apply。internal通常不带锁或不触发状态检查,用于 Recovery 期间的高效回放。 - 关键函数:
kvstore_apply_put_internal():纯粹的内存指针操作。kvstore_replay_put():被 Recovery 调用,跳过日志写入阶段,直接调用 Apply。
5. Maintenance 层(维护/压缩)
核心逻辑:解决日志无限增长的问题。
- **设计原因:**日志文件不能一直增加,否则恢复太慢,
Compaction通过将当前内存状态存为新快照并删除旧日志来释放空间。 - 关键函数:
kvstore_maybe_compact(): 自动检查(基于阈值)。kvstore_compaction_internal(): 执行合并,期间可能需要切换状态机防止并发冲突。snapshot_write_cb():回调函数,用于在遍历内存数据时写入磁盘。
6. State Machine 层 (状态机)
核心逻辑:管理系统的生存周期(Ready, Recovering, Compaction, Failed)。
- 关键函数:
kvstore_transit_state(): 状态转移触发器。kvstore_enter_failed(): 一旦发生不可逆的 IO 错误,立即进入失败态,保护数据。
7. Error 层(诊断)
核心逻辑:提供人类可读的上下文。
- 关键函数:
kvstore_strerror(): 将内部错误码转为字符串。crc32(): 用于检测日志条目是否损坏。
核心写入流程
当调用
kvstore_put(key, val)时,内部发生了什么?
API 入口:
kvstore_put()调用kvstore_exec_write()。状态检查:
kvstore_state_allow()确认当前是READY状态持久化(Logging):
kvstore_log_put()将数据写入磁盘。修改内存(Apply):
kvstore_apply_put()更新内存索引。维护检查(Maintenance):
kvstore_maybe_compact()判断是否需要压缩。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 butterfly!