L1 · 文件 IO · WAL · 崩溃一致性
单机存储引擎
分布式系统的地基是单机引擎。把你运维时熟悉的 page cache、fsync、坏盘现象翻译成代码:亲手写出带校验和、带 WAL、崩溃后能恢复的存储引擎。
本阶段出口:里程碑① forge-store:单机 blob 引擎,kill -9 后重启数据不丢不坏。
5 节课 · 约 5 小时已完成 0/5
- 1
文件 IO 的三条通路
编码50mbuffered、O_DIRECT、mmap 三种写法各自经过哪些内核层?fsync 到底保证了什么?运维时背过的结论,这次用 Rust 代码逐一验证。
- 写出三种 IO 通路的 Rust 代码并测出性能差异
- 解释 fsync / fdatasync / O_DSYNC 的语义区别
- 说清为什么存储引擎几乎都绕开 page cache
- 2
从零写一个 blob store
编码60m设计 forge-store 的盘上格式:定长 superblock、extent 分配、每块数据带 crc32c 校验。你将第一次体会「格式定了就改不动」的敬畏感。
- 设计并文档化一个版本化的盘上格式
- 实现 extent 分配器的最简版本(bitmap)
- 写读路径时校验 crc32c,损坏时返回明确错误
- 3
WAL 与崩溃一致性
编码60m突然断电时写到一半的数据怎么办?Write-Ahead Log 是所有存储系统的标准答案。实现追加日志、torn write 检测和启动时的恢复重放。
- 解释 torn write、reorder、fsync 丢失三种崩溃场景
- 实现带长度前缀 + 校验和的日志记录格式
- 写出启动恢复逻辑:扫到损坏记录即截断
- 4
内存索引与日志结构存储
编码60m把 WAL 和 blob store 组装成完整引擎:内存 HashMap 索引 + 日志结构数据文件 + 后台 GC。Bitcask 模型,Weka 元数据层的迷你原型。
- 解释日志结构存储为什么对 SSD 友好
- 实现启动时从数据文件重建内存索引
- 实现最简 GC:拷贝存活数据、原子切换
- 5
里程碑①:kill -9 验收
里程碑45m给 forge-store 上酷刑:随机写入中 kill -9、写入中拔盘(dm-flakey)、注入位翻转。全部扛住才算过关 —— 验收标准就是这节课的脚本。
- 跑通崩溃注入测试脚本并解读结果
- 用 AI 分析一次真实的数据损坏 case
- 写出本阶段的设计文档:格式、不变量、已知限制