1、什麼是快照mysql
快照(snapshot)是最簡單的壓縮方式。在快照中,所有的當前系統狀態都被寫入到快照中,存儲到持久化的存儲中,而後在那個時刻以前的所有日誌均可以被丟棄。算法
打個比方,像Redis這樣的KV系統,系統的當前狀態就是當前全部key的值及過時時間,把這些信息所有寫入到磁盤中就是快照。sql
2、Raft算法中爲何須要快照spa
Raft算法是經過日誌來保證節點最終一致的,而日誌是持續增長的,對於一個7*24小時運行的系統,日誌會一直增長,這樣致使幾個問題:日誌
一、磁盤佔用空間過大;blog
二、新的節點加入進來後,須要同步的日誌太多,進一步影響系統的可用性;索引
還有1點不是Raft算法中自己的功能,就是恢復數據,即一個誤操做須要回滾,則須要回放從前到後全部日誌,這個時間會很是長,這時若是有快照就能夠快速恢復了。rem
mysql binlog、Redis的aof文件其實就至關於快照,只不過這些系統沒有實現Raft算法。同步
3、與快照相關的RPCit
一、安裝快照 RPC(InstallSnapshot RPC)
對於接收方規則以下
這些規則大部分應該好理解,部分規則解釋下:
五、保存快照文件,丟棄全部存在的或者部分有着更小索引號的快照
假如說Follower已經有快照了,而且快照最後索引爲1000,而新的快照的索引爲2000,則將前面的快照丟棄
六、若是現存的日誌擁有相同的最後任期號和索引值,則後面的數據繼續保留而且回覆
意思說接收節點若是有相應的日誌了,則後面的日誌保留,此消息能夠直接回復。
打個比方,若是Follower B的索引已經到2002,此索引對應的term爲102,其中2000索引的term爲101,若是這時收到一個安裝快照的消息,最後1條的term爲101,最後1條的索引爲2000,經過對比發現此日誌已經存在節點上,而且Term也對的上,所以2001以後的日誌保留。
七、丟棄所有日誌
上面條件知足後,將快照保存到本地,本地全部日誌所有丟棄。
固然前提是前面的條件都不知足,具體不細述。
八、可以使用快照來恢復狀態機(而且裝載快照中的集羣配置)
恢復狀態機就不用說了,直接拿快照恢復狀態機的數據,舉例來講KV系統,發送的快照若是隻有a=1, b=2這樣的狀態,即把全部數據清空,只保留上面2條數據。
而且裝載快照中的集羣配置,意思是說快照還包含集羣配置信息,主是要爲了支持集羣成員更新;
因此快照必須如下信息:
最後一條日誌的Index;
最後一條日誌的Term;
生成快照時的集羣配置信息;
狀態機數據;
4、其它細節
一、什麼時候生成快照
這個Raft算法並無規定,看應用本身實現,像etcd是10000日誌後產生1次快照,須要根據實際條件選擇。
二、誰生成日誌快照
Raft算法並無規定誰能夠生成,即誰均可以生成,即符合條件1就能夠生成,主要是爲了切換爲Leader的時候能夠快速應對新節點添加數據的狀況。由於只有數據一致,誰生成都是同樣的。