Raft state of log
commitIndex : A log entry is committed once the leader that created the entry has replicated it on a majority of the servers.
在大多數服務器上復制了該條日志,則該條日志的index可以被認為是commited
lastApplied : 上一個被狀態機應用的index
這2個屬性都被標注了 volatile
Impl in Etcd
日志復制分為了2個階段的過程,commit和apply,commit是raft狀態機間相互確認日志同步的過程,apply是應用處理好相關日志並通知raft狀態機已被應用的過程
apply的過程較為抽象,由應用來決定業務上需要apply的過程,實際上是應用commited的日志的應用邏輯,在完成邏輯后,只是向raft狀態機標記日志被應用方處理了
Structure
主要由2個包組成,
pkg raft 是raft算法的具體實現
pkg etcdserver作為使用raft算法的應用,包含具體的應用邏輯與交互膠水
pkg raft
pkg etcdserver
remote request sequential flow
raft msg handle sequential flow
就是試試mermaid,還蠻好用的
Flow
Commit flow
proposal
follower accept proposal
leader commit proposal
除開SnapShot以及重啟節點的特殊邏輯,正常啟動一個Node,在Storage中實際上存儲了uncommited&commited的日志,並且在啟動時設置了commitedIndex就是日志的最大長度,某些極端情況下,日志會有不同,所以在Follower accept proposal的過程中,會有檢測沖突的過程,以及Leader強制Follower跟隨自己的日志
apply flow
每個節點都會有自己的applied index,並不需要同步。
流程見 raft msg handle sequential flow
這一步 Node(pkg raft): call ready(), collect entries from raft log & msgs needs handle ,會生成 Ready 數據,里面包含untable entries,以及 committed entries。其中Entries字段實際上是包含了 raftlog中 unstable 的日志,里面含有uncommitted&committed的日志,因為沒有被標記成applied,所以是 unstable的。
Ready通過channel數據傳輸至 EtcdServer后,在這里應用層的邏輯就會執行,存儲,應用,之后mark 日志為 applied,並且將unstable中applied的日志清除掉。
Summary
缺失了snapshot,log compact ,leader change , config change , read linear的流程。
在交互上還未去確認的地方,是否applied過后的日志才被etcd承認,按照目前的流程,其實commit過后的,雖然有可能會丟失,但也可以被承認如果是樂觀看待的話。