Skip to main content

Log

Struct Log 

Source
pub struct Log {
    pub engine: Box<dyn Engine>,
    /* private fields */
}
Expand description

Raft 日志保存一系列任意命令(通常是写操作),在节点间复制,并顺序应用到本地状态机。 每条日志含索引、命令,以及领导者提出它时的任期。命令可为 noop(None), 在选出领导者时追加(见论文 5.4.2 节)。示例:

IndexTermCommand
11None
21CREATE TABLE table (id INT PRIMARY KEY, value STRING)
31INSERT INTO table VALUES (1, ‘foo’)
42None
52UPDATE table SET value = ‘bar’ WHERE id = 1
62DELETE 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

Source

pub fn new(engine: Box<dyn Engine>) -> Result<Self>

使用给定存储引擎初始化日志。

Source

pub fn get_first_index(&self) -> Index

日志中仍保留的第一条索引。

Source

pub fn get_snapshot_meta(&self) -> (Index, Term)

快照基座:(last_included_index, last_included_term);无快照时 (0,0)

Source

pub fn compact_to( &mut self, last_included_index: Index, last_included_term: Term, ) -> Result<()>

截断并删除 <= last_included_index 的日志条目(快照后压缩)。

Source

pub fn reset_with_snapshot( &mut self, last_included_index: Index, last_included_term: Term, ) -> Result<()>

安装快照后重置日志:丢弃全部条目,仅保留快照基座。

Source

pub fn enable_fsync(&mut self, fsync: bool)

控制是否对写入做 fsync。关闭可能违反 Raft 保证,见 fsync 字段注释。

Source

pub fn get_commit_index(&self) -> (Index, Term)

返回 commit 索引与任期。

Source

pub fn get_last_index(&self) -> (Index, Term)

返回最后一条日志的索引与任期。

Source

pub fn get_term_vote(&self) -> (Term, Option<NodeID>)

返回当前任期(无则为 0)与投票。

Source

pub fn set_term_vote(&mut self, term: Term, vote: Option<NodeID>) -> Result<()>

保存当前任期与投票(若有)。强制任期不回退,且一个任期内只投一票。 append() 使用此任期;splice() 不能写入超过该任期的条目。

Source

pub fn append(&mut self, command: Option<Vec<u8>>) -> Result<Index>

在当前任期向日志追加命令并刷盘,返回其索引。 None 表示 noop 命令,通常在 Raft 领导者变更后使用。

Source

pub fn append_membership( &mut self, membership: MembershipEntry, ) -> Result<Index>

追加一条成员配置变更日志。

Source

pub fn append_entry( &mut self, command: Option<Vec<u8>>, membership: Option<MembershipEntry>, ) -> Result<Index>

追加完整条目字段。

Source

pub fn latest_membership(&mut self) -> Result<Option<(Index, MembershipEntry)>>

从日志中扫描最新的成员配置条目(若有)。

Source

pub fn commit(&mut self, index: Index) -> Result<Index>

提交到给定索引(含)。该索引必须存在且不早于当前 commit 索引。

Source

pub fn get(&mut self, index: Index) -> Result<Option<Entry>>

获取指定索引的条目;不存在则返回 None。

Source

pub fn has(&mut self, index: Index, term: Term) -> Result<bool>

检查日志是否包含给定索引与任期的条目。

Source

pub fn scan(&mut self, range: impl RangeBounds<Index>) -> Iterator<'_>

返回给定索引范围内的日志条目迭代器。

Source

pub fn scan_apply(&mut self, applied_index: Index) -> Iterator<'_>

返回可应用条目的迭代器:从当前 applied 索引之后到 commit 索引。

Source

pub fn splice(&mut self, entries: Vec<Entry>) -> Result<Index>

将一组条目拼接到日志并刷盘。新索引会追加。 重叠且任期相同的索引必须相等并被忽略;重叠但任期不同时, 在首个冲突处截断现有日志,再拼接新条目。

条目索引必须连续、任期相等或递增;首条索引须在 [1, last_index+1] 内, 任期不低于前一条(base)且不超过当前任期。

Source

pub fn status(&mut self) -> Result<Status>

返回日志引擎状态。

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.