MongoDB复制集与Raft协议异同点分析
此文已由作者溫正湖授權網易云社區發布。
歡迎訪問網易云社區,了解更多網易技術產品運營經驗。
一、日志復制流程:
a、raft leader節點在接收client請求后,先將請求寫到日志中,再將日志通過AppendEntries RPC發送到follow上。如果收到了大多數follow的確認消息,則對應日志可以在leader節點回放,之后follow上對應的日志也會被應用;
b、mongodb primary節點在接收到client/driver請求后,將數據變化寫到數據庫上,同時寫一份日志到oplog.rs集合中,secondary節點通過tail cursor將日志從primary(或sync source,即復制源)拉取到本地馬上進行回放(不會像mysql relay一樣緩存到磁盤上),回放完成前將對應的oplog日志保存到本節點的oplog.rs集合。
//顯然有幾點不一樣:
1、raft是主動推日志,mongodb是secondary拉日志; 相對來說,拉取的方式可以減輕主節點的負擔。這點mongodb好些。
2、raft先寫日志,日志發送到大多數節點后再應用到狀態機。mongodb是先寫數據,然后寫日志,再通過日志拉取的方式應用到從節點。 如果日志比數據小,那么raft更具有性能優勢,否則,相差無幾。
二、什么時候返回客戶端:
a、raft中, 是大多數節點已收到,還是寫入leader日志時? 通過“● Once new entry committed: ? Leader executes command in its state machine, returns result to client”這句話可以知道,raft是等大多數節點收到日志,leader將日志應用到本節點后才返回客戶端;
b、mongodb中,什么時候返回客戶端可以由用戶進行動態設置,設置項為writeConcern,通過rs.conf()可以獲取當前默認的writeConcern,默認置為w=1,即寫了primary后即返回。也可以在每次寫操作時設置writeConcern,主要包括寫入到幾個節點,寫入超時是多少,是否需要寫日志等。
// 所以,在這點上mongodb更加靈活,但早期設置的writeConcern級別太松,導致丟數據嚴重。目前設置為寫了primary節點再返回客戶端。
三、從節點什么時候應用日志:
a、raft中,AppendEntries RPC攜帶了當前已經committed的log的信息,這樣從節點就可以根據該信息來將這之前的log應用到本節點;
b、mongod中,從節點從復制源獲取oplog信息后,馬上在本節點并行回放;
//這點,mongod會更加簡潔。
四、誰能成為主節點:
a、raft,“Only servers with up-to-date logs can become leader”只有擁有最新數據的節點才能成為主。// 4.21更新,raft也是跟MongoDB復制集一樣,數據比大多數節點性就可以。官方ppt中的這句話,up-to-date翻譯成最新容易引起誤解。
b、數據比大多數節點新就可以成為主節點,新主節點在提供對外服務前,會有catchupTimeoutMills時間的catchup過程,用來短暫復制其他節點更新的數據;
//數據是否比大多數節點新,判斷依據是根據日志來的
五、如何確保每個節點在一個term中只投票一次:
a、raft “Each server gives only one vote per term (persist on disk)”,也就是說會將相應信息持久化到磁盤上,具體可參考mongodb。
b、mongodb將投票信息持久化到local庫下replset.election中,內容如:{ "_id" : ObjectId("58cbe1844857daa6e06ed9da"), "term" : NumberLong(4), "candidateIndex" : NumberLong(0) },記錄了在那個term中給誰(candidateIndex)投票了。通過_id字段的ObjectId對象能獲取投票時間。
六、新主是否會做catchup:
a、raft,“Leader’s log is “the truth””,主節點的數據是真理,新主產生后,不會從存活的從節點上拷最新的數據;
b、mongodb,默認會有2s的catchup時間,如果發現從節點數據比新主新,那么在這時間內會catchup
//兩則不同的原因是,mongodb是個AP系統,C無法滿足。存在2種情況,如果設置為w=1,那么如果主掛了,數據可能丟失。如果w=majority,那么如果還未滿足majority時,主掛了,也就是說客戶端返回錯誤,但這并不表示數據就寫入失敗了,需要等新主產生后進一步確認,因為即使新主本來沒有這部分數據,也可能在catchup節點從其他節點獲取。所以,這跟mysql等關系型數據庫不一樣。
七、主怎么知道從已經收到日志/回放了:
a、raft,通過AppendEntries RPC返回結果;
b、通過replSetUpdatePosition命令;
replSetUpdatePosition不是周期性的,而是實時的。從節點每完成一次oplog回放,就向其復制源發送一個replSetUpdatePosition命令。
八、節點間是否有優先級:
a、raft,大家都是平等的。
b、mongodb,有優先級概念,priority可以是非負數。浮點型
九、是否支持鏈式復制:
a、raft,不支持;
b、mongodb支持鏈式復制。好處是減小了主上的壓力。尤其是在有很多從節點的場景下。不足之處是,這容易導致某些從節點的復制延遲過大。
網易云免費體驗館,0成本體驗20+款云產品!?
更多網易技術、產品、運營經驗分享請點擊。
相關文章:
【推薦】?網易云容器服務微服務化實踐—微服務測試及鏡像化提測全流程實踐
【推薦】?流式斷言器AssertJ介紹
【推薦】?【網易嚴選】iOS持續集成打包(Jenkins+fastlane+nginx)
轉載于:https://www.cnblogs.com/zyfd/p/9814614.html
總結
以上是生活随笔為你收集整理的MongoDB复制集与Raft协议异同点分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: webpack4.0 babel配置遇到
- 下一篇: js for循环与for in循环的区别