数据树与事务持久化
This content is not available in your language yet.
先给答案:DataTree、TxnLog、快照恢复和日志滚动的源码链路
Section titled “先给答案:DataTree、TxnLog、快照恢复和日志滚动的源码链路”DataTree、TxnLog、快照恢复和日志滚动的源码链路。 正文沿“数据结构 -> 为什么日志和快照都要有”展开:先确认入口和状态归属,再跟踪控制流或数据流的推进,最后落到对外可观察的结果。
主要失效边界集中在“dataDir 与 logDir 共盘、快照过大、磁盘满”这些场景。它们破坏的是容量、顺序、并发或生命周期前提;排查时应先确认状态是否仍由正确对象持有,再核对推进条件和清理路径。
FileTxnSnapLog -> TxnLog: txnlog.* -> SnapShot: snapshot.* -> restore() -> DataTree.processTxn()写请求先在 PrepRequestProcessor 生成事务记录,SyncRequestProcessor 负责日志同步和 fsync 策略,最终 FinalRequestProcessor 把事务应用到 DataTree。快照降低恢复时需要重放的日志数量。
关键坐标:
FileTxnSnapLog#append—zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java:213FileTxnSnapLog#commit—zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java:230FileTxnSnapLog#restore—zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnSnapLog.java:254FileTxnLog#append—zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnLog.java:220FileTxnLog#commit—zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/FileTxnLog.java:292SerializeUtils#deserializeSnapshot—zookeeper-server/src/main/java/org/apache/zookeeper/server/util/SerializeUtils.java:142SerializeUtils#deserializeTxn—zookeeper-server/src/main/java/org/apache/zookeeper/server/util/SerializeUtils.java:190DataTree#serialize—zookeeper-server/src/main/java/org/apache/zookeeper/server/DataTree.java:1252DataTree#deserialize—zookeeper-server/src/main/java/org/apache/zookeeper/server/DataTree.java:1276SyncRequestProcessor#flush—zookeeper-server/src/main/java/org/apache/zookeeper/server/SyncRequestProcessor.java:204
为什么日志和快照都要有
Section titled “为什么日志和快照都要有”替代方案:只保留完整快照,写入会复制整棵树;只保留日志,恢复会重放无限历史。选择:快照提供基线,日志覆盖快照后的增量。
| 场景 | 现象 | 原因 | 规避 |
|---|---|---|---|
| dataDir 与 logDir 共盘 | 延迟抖动 | fsync 与快照争用 IO | 分离磁盘 |
| 快照过大 | 恢复慢 | 序列化和加载成本高 | 调整 snapCount |
| 磁盘满 | 写失败 | 日志无法追加 | 监控磁盘与 purge |
事件日志加周期快照是持久化状态机的通用优化;恢复时先加载基线,再重放边界之后的事件。
面试锚点
- 重启时如何恢复 DataTree?
- 为什么不能只用快照或只用日志?
- fsync 策略影响什么一致性边界?