3、以上關(guān)于接受Ready()消息的處理代碼中,除了之前提到的兩點(diǎn)外,剩下的就是關(guān)于WAL(Write Ahead Logging 預(yù)寫式日志多用于實(shí)現(xiàn)數(shù)據(jù)庫原子性事務(wù))和snapshot的相關(guān)處理了。
通過代碼看到Ready()里收到的每一條消息都會先調(diào)用wal。Save,由wal。Save將相關(guān)的信息保存到WAL中,當(dāng)操作積累到一定的數(shù)量時,則會通過saveSnapshot將目前的全量數(shù)據(jù)(包括狀態(tài)和已經(jīng)接受到的所有數(shù)據(jù))保存到snapshot中, 然后調(diào)用wal。ReleaseLockTo釋放掉已經(jīng)存入snapshot中的操作。
這點(diǎn)與許多數(shù)據(jù)庫實(shí)現(xiàn)的WAL原理( WAL機(jī)制的原理,是修改并不寫入到數(shù)據(jù)庫文件中,而是寫入到另外一個稱為WAL的文件中;如果事務(wù)失敗,WAL中的記錄會被忽略,撤銷修改;如果事務(wù)成功,它將在隨后的某個時間被寫回到數(shù)據(jù)庫文件中,提交修改)是一樣的。
注:最后別忘了調(diào)用RaftNode。Advance()。
關(guān)于日志壓縮
之前提到WAL會將RaftNode的每次操作記錄下來,而且在RaftCluster中l(wèi)eader不刪除日志,僅追加日志,因此隨著系統(tǒng)的持續(xù)運(yùn)行,WAL中內(nèi)容越來越多,導(dǎo)致日志重放時間增長,系統(tǒng)可用性下降。快照(Snapshot)是用于“日志壓縮”最常見的手段,Raft也不例外。
具體做法如下所示(圖片來自網(wǎng)絡(luò)):
與Raft其它操作Leader-Based不同,snapshot是由各個節(jié)點(diǎn)獨(dú)立生成的。除了日志壓縮的功能,snapshot還可以用于同步狀態(tài)。
四、總結(jié)
以上僅僅只是跑起來一個簡單的RaftCluster,關(guān)于服務(wù)怎么和嵌入的RaftCluster結(jié)合,以及l(fā)eader切換,節(jié)點(diǎn)的增刪等等還是有不少的問題等著我們一起去探討和解決。有關(guān)Raft的更多資料可以參考: