Storage
Storage 是 Core 层访问稳定存储的抽象接口,定义位于 include/raftpp/core/storage.h。
InitialState()Entries(low, high, max_size, context)Term(idx)FirstIndex()LastIndex()GetSnapshot(request_index, to)
InitialState()
Section titled “InitialState()”返回 RaftState,包含:
HardStateConfState
启动恢复时,RawNode 会基于该结果恢复当前持久化状态。
Entries(low, high, max_size, context)
Section titled “Entries(low, high, max_size, context)”返回区间 [low, high) 内的日志条目。
语义要点:
max_size指定返回的最大字节数上限。- 即使设置了
max_size,也应至少返回一条 entry。 context用于说明此次取日志的用途,例如发送追加、生成Ready或其他内部路径。
Term(idx)
Section titled “Term(idx)”返回指定索引的 term。
语义要点:
- 存储实现需要正确处理快照边界。
- 对已经被压缩的日志索引,应返回与压缩语义一致的错误。
FirstIndex() 与 LastIndex()
Section titled “FirstIndex() 与 LastIndex()”FirstIndex()返回当前存储中第一个可用日志索引。LastIndex()返回当前最后一个可用日志索引。
它们定义了当前存储持有日志的有效区间。
GetSnapshot(request_index, to)
Section titled “GetSnapshot(request_index, to)”返回可用于发送或恢复的快照。
如果快照尚未准备好,可以返回临时不可用错误,而不是伪造一个不完整快照。
MemoryStorage
Section titled “MemoryStorage”MemoryStorage 是最直接的参考实现,额外提供以下便捷能力:
Append()Compact()ApplySnapshot()AllEntries()- 故障注入辅助接口,例如
TriggerSnapshotUnavailable()
如果需要理解接口的最小正确实现,可先阅读 MemoryStorage。
WritableStorage
Section titled “WritableStorage”WritableStorage 在 Storage 基础上增加写接口:
Append(entries)SetHardState(hs)SetConfState(conf_state)ApplySnapshot(snapshot)Sync()LocalSnapshot()LogSizeBytes()
LocalSnapshot() 用于启动时恢复本地快照,LogSizeBytes() 用于基于 WAL 目录体积的自动快照触发。
与 Raftor 的关系
Section titled “与 Raftor 的关系”Raftor::Create(config, state_machine, storage, transport) 当前接收 std::shared_ptr<WritableStorage>,调用方可以注入自定义可写存储和自定义传输。
因此:
- Core 层可基于任意
Storage实现工作。 - Raftor 层需要
WritableStorage,因为它负责持久化Ready中的 entries、hard state、conf state 和 snapshot。 - 如果注入的存储不是
WALStorage,Raftor 仍可运行,但不会使用 WAL 地址簿能力;peer 地址恢复将依赖启动配置或调用方自定义传输。
自定义存储实现注意事项
Section titled “自定义存储实现注意事项”- 返回的索引区间必须与
FirstIndex()/LastIndex()一致。 - 不能返回破坏日志连续性的结果。
- 快照边界与日志边界必须一致。
- 如果支持异步取日志,应正确处理
GetEntriesContext。 Sync()必须满足Ready.must_sync对落盘可见性的要求。- 如果实现
LocalSnapshot(),返回的快照会在Raftor::Create()时先恢复到状态机,并作为RawNode的初始 applied index。