Skip to content

Storage

Storage 是 Core 层访问稳定存储的抽象接口,定义位于 include/raftpp/core/storage.h

  • InitialState()
  • Entries(low, high, max_size, context)
  • Term(idx)
  • FirstIndex()
  • LastIndex()
  • GetSnapshot(request_index, to)

返回 RaftState,包含:

  • HardState
  • ConfState

启动恢复时,RawNode 会基于该结果恢复当前持久化状态。

返回区间 [low, high) 内的日志条目。

语义要点:

  • max_size 指定返回的最大字节数上限。
  • 即使设置了 max_size,也应至少返回一条 entry。
  • context 用于说明此次取日志的用途,例如发送追加、生成 Ready 或其他内部路径。

返回指定索引的 term。

语义要点:

  • 存储实现需要正确处理快照边界。
  • 对已经被压缩的日志索引,应返回与压缩语义一致的错误。
  • FirstIndex() 返回当前存储中第一个可用日志索引。
  • LastIndex() 返回当前最后一个可用日志索引。

它们定义了当前存储持有日志的有效区间。

返回可用于发送或恢复的快照。

如果快照尚未准备好,可以返回临时不可用错误,而不是伪造一个不完整快照。

MemoryStorage 是最直接的参考实现,额外提供以下便捷能力:

  • Append()
  • Compact()
  • ApplySnapshot()
  • AllEntries()
  • 故障注入辅助接口,例如 TriggerSnapshotUnavailable()

如果需要理解接口的最小正确实现,可先阅读 MemoryStorage

WritableStorageStorage 基础上增加写接口:

  • Append(entries)
  • SetHardState(hs)
  • SetConfState(conf_state)
  • ApplySnapshot(snapshot)
  • Sync()
  • LocalSnapshot()
  • LogSizeBytes()

LocalSnapshot() 用于启动时恢复本地快照,LogSizeBytes() 用于基于 WAL 目录体积的自动快照触发。

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 地址恢复将依赖启动配置或调用方自定义传输。
  • 返回的索引区间必须与 FirstIndex() / LastIndex() 一致。
  • 不能返回破坏日志连续性的结果。
  • 快照边界与日志边界必须一致。
  • 如果支持异步取日志,应正确处理 GetEntriesContext
  • Sync() 必须满足 Ready.must_sync 对落盘可见性的要求。
  • 如果实现 LocalSnapshot(),返回的快照会在 Raftor::Create() 时先恢复到状态机,并作为 RawNode 的初始 applied index。