早在2013年11月份,在raft論文還只能在網(wǎng)上下載到草稿版時(shí),我曾經(jīng)寫過(guò)一篇blog對(duì)其進(jìn)行簡(jiǎn)要分析。4年過(guò)去了,各種raft協(xié)議的講解鋪天蓋地,raft也確實(shí)得到了廣泛的應(yīng)用。其中最知名的應(yīng)用莫過(guò)于etcd。etcd將raft協(xié)議本身實(shí)現(xiàn)為一個(gè)library,位于https://github.com/coreos/etcd/tree/master/raft,然后本身作為一個(gè)應(yīng)用使用它。
本文不講解raft協(xié)議核心內(nèi)容,而是站在一個(gè)etcd raft library使用者的角度,講解要用上這個(gè)library需要了解的東西。
這個(gè)library使用起來(lái)相對(duì)來(lái)說(shuō)還是有點(diǎn)麻煩。官方有一個(gè)使用示例在 https://github.com/coreos/etcd/tree/master/contrib/raftexample。整體來(lái)說(shuō),這個(gè)庫(kù)實(shí)現(xiàn)了raft協(xié)議核心的內(nèi)容,比如append log的邏輯,選主邏輯,snapshot,成員變更等邏輯。需要明確的是:library沒(méi)有實(shí)現(xiàn)消息的網(wǎng)絡(luò)傳輸和接收,庫(kù)只會(huì)把一些待發(fā)送的消息保存在內(nèi)存中,用戶自定義的網(wǎng)絡(luò)傳輸層取出消息并發(fā)送出去,并且在網(wǎng)絡(luò)接收端,需要調(diào)一個(gè)library的函數(shù),用于將收到的消息傳入library,后面會(huì)詳細(xì)說(shuō)明。同時(shí),library定義了一個(gè)Storage接口,需要library的使用者自行實(shí)現(xiàn)。
Storage接口如下:
// Storage is an interface that may be implemented by the application// to retrieve log entries from storage.//// If any Storage method returns an error, the raft instance will//&nb