pub struct Log {
pub engine: Box<dyn Engine>,
/* private fields */
}Expand description
Raft 日志保存一系列任意命令(通常是写操作),在节点间复制,并顺序应用到本地状态机。 每条日志含索引、命令,以及领导者提出它时的任期。命令可为 noop(None), 在选出领导者时追加(见论文 5.4.2 节)。示例:
| Index | Term | Command |
|---|---|---|
| 1 | 1 | None |
| 2 | 1 | CREATE TABLE table (id INT PRIMARY KEY, value STRING) |
| 3 | 1 | INSERT INTO table VALUES (1, ‘foo’) |
| 4 | 2 | None |
| 5 | 2 | UPDATE table SET value = ‘bar’ WHERE id = 1 |
| 6 | 2 | DELETE FROM table WHERE id = 1 |
注意这只是示意;实际命令不必是 SQL,而是任意底层写操作。
使用键值存储按索引落盘日志条目,以及若干元数据键(例如本任期投票给了谁)。
稳态下日志只追加:客户端提交命令后,领导者经 Log::append 写入本地日志,
再复制给跟随者,跟随者经 Log::splice 追加。当某索引已复制到多数节点时
即变为已提交,此前日志不可变,并保证最终所有节点都会拥有它。
节点通过 Log::commit 跟踪 commit 索引,并将已提交命令应用到状态机。
但未提交条目可被替换或删除。领导者可能已追加却无法达成共识 (例如无法与多数节点通信)。若另选新领导者并在相同索引写入不同命令, 旧领导者或跟随者发现后,会用新领导者的条目替换未提交部分。
Raft 日志不变量:
- 条目索引从 1 起连续(无空洞)。
- 条目任期相对前一条从不下降。
- 条目任期不超过当前任期。
- 追加的条目是持久的(刷盘)。
- 追加的条目使用当前任期。
- 已提交条目在快照后可截断前缀(见
Log::compact_to)。 - 已提交条目最终会复制到所有节点。
- 相同索引/任期的条目含相同命令。
- 若两份日志在某索引/任期匹配,则此前所有条目相同(见论文 5.3 节)。
Fields§
§engine: Box<dyn Engine>底层存储引擎。使用 trait 对象而非泛型,以便运行时选择引擎, 并避免把泛型参数传遍整个 Raft。
Implementations§
Source§impl Log
impl Log
Sourcepub fn get_first_index(&self) -> Index
pub fn get_first_index(&self) -> Index
日志中仍保留的第一条索引。
Sourcepub fn get_snapshot_meta(&self) -> (Index, Term)
pub fn get_snapshot_meta(&self) -> (Index, Term)
快照基座:(last_included_index, last_included_term);无快照时 (0,0)。
Sourcepub fn compact_to(
&mut self,
last_included_index: Index,
last_included_term: Term,
) -> Result<()>
pub fn compact_to( &mut self, last_included_index: Index, last_included_term: Term, ) -> Result<()>
截断并删除 <= last_included_index 的日志条目(快照后压缩)。
Sourcepub fn reset_with_snapshot(
&mut self,
last_included_index: Index,
last_included_term: Term,
) -> Result<()>
pub fn reset_with_snapshot( &mut self, last_included_index: Index, last_included_term: Term, ) -> Result<()>
安装快照后重置日志:丢弃全部条目,仅保留快照基座。
Sourcepub fn enable_fsync(&mut self, fsync: bool)
pub fn enable_fsync(&mut self, fsync: bool)
控制是否对写入做 fsync。关闭可能违反 Raft 保证,见 fsync 字段注释。
Sourcepub fn get_commit_index(&self) -> (Index, Term)
pub fn get_commit_index(&self) -> (Index, Term)
返回 commit 索引与任期。
Sourcepub fn get_last_index(&self) -> (Index, Term)
pub fn get_last_index(&self) -> (Index, Term)
返回最后一条日志的索引与任期。
Sourcepub fn get_term_vote(&self) -> (Term, Option<NodeID>)
pub fn get_term_vote(&self) -> (Term, Option<NodeID>)
返回当前任期(无则为 0)与投票。
Sourcepub fn set_term_vote(&mut self, term: Term, vote: Option<NodeID>) -> Result<()>
pub fn set_term_vote(&mut self, term: Term, vote: Option<NodeID>) -> Result<()>
保存当前任期与投票(若有)。强制任期不回退,且一个任期内只投一票。 append() 使用此任期;splice() 不能写入超过该任期的条目。
Sourcepub fn append(&mut self, command: Option<Vec<u8>>) -> Result<Index>
pub fn append(&mut self, command: Option<Vec<u8>>) -> Result<Index>
在当前任期向日志追加命令并刷盘,返回其索引。 None 表示 noop 命令,通常在 Raft 领导者变更后使用。
Sourcepub fn append_membership(
&mut self,
membership: MembershipEntry,
) -> Result<Index>
pub fn append_membership( &mut self, membership: MembershipEntry, ) -> Result<Index>
追加一条成员配置变更日志。
Sourcepub fn append_entry(
&mut self,
command: Option<Vec<u8>>,
membership: Option<MembershipEntry>,
) -> Result<Index>
pub fn append_entry( &mut self, command: Option<Vec<u8>>, membership: Option<MembershipEntry>, ) -> Result<Index>
追加完整条目字段。
Sourcepub fn latest_membership(&mut self) -> Result<Option<(Index, MembershipEntry)>>
pub fn latest_membership(&mut self) -> Result<Option<(Index, MembershipEntry)>>
从日志中扫描最新的成员配置条目(若有)。
Sourcepub fn scan(&mut self, range: impl RangeBounds<Index>) -> Iterator<'_>
pub fn scan(&mut self, range: impl RangeBounds<Index>) -> Iterator<'_>
返回给定索引范围内的日志条目迭代器。
Sourcepub fn scan_apply(&mut self, applied_index: Index) -> Iterator<'_>
pub fn scan_apply(&mut self, applied_index: Index) -> Iterator<'_>
返回可应用条目的迭代器:从当前 applied 索引之后到 commit 索引。
Auto Trait Implementations§
impl !RefUnwindSafe for Log
impl !Sync for Log
impl !UnwindSafe for Log
impl Freeze for Log
impl Send for Log
impl Unpin for Log
impl UnsafeUnpin for Log
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more