raft read query

Processing read-only queries more efficiently

前言:

raft 的論文也看了很多遍, 其中輕描淡寫的說了leased-base的讀。 etcd的raft源碼實現(xiàn)也看了幾次, 有幾個點特別不理解, 直到去看readme.md的時候,才注意到這個https://ramcloud.stanford.edu/~ongaro/thesis.pdf(哎, 不讀文檔害死人呀,以后看什么一定要先讀文檔), 這不是論文, 更像一本書, 涉及到了raft方方面面.
整體步驟

  1. 如果leader還沒有提交entry, 他必須等待直到有entry提交. leader完整性規(guī)則保證了該leader擁有提交過的entry, 但是在當他被選擇為leader的時候, 他并不知道那些那些是已經(jīng)提交的entry, 所以他會在成為leader之后, 首先提交一個空entry作為自己item的開始, 一旦該空entry提及提交成功,該leader的commmited idx 至少和其他server上的commit idx一樣大(也就是說:剛成為leader的時候, leader的commitidx 不一定是最大的)

  2. leader 把最新的commit idx保存在本地變量readindex里

  3. leader必須保證自己不被其他new leader替代(并且自己還沒有意識到自己被替代)。 leader向其他server發(fā)送一輪hb,并且檢驗自己能不能被過半server回復, 一旦被集群過半server回復,該leader就能至少保證在他發(fā)送hb的那一刻,集群中沒有其他leader, 因此,自己本地保存的readindex仍然是最大.

  4. leader等state machine至少applied和readindex一樣大, 這種情況下, 就能滿足強一致。

  5. 最后,leader把用戶查詢賦給狀態(tài)機, 并且給客戶端回復。

alternative(一)

為了提高集群的吞吐量,分擔leader的壓力, 可以讓follower承擔讀的請求。 但若沒有一些措施,可能讀到過期數(shù)據(jù),比如L:分區(qū)follower可能一段時間內并沒有接受到任何新的entry, 甚至該follower確實接受到了leader的hb, 但是該leader其實并不是當前集群的leader, 只是該leader自己還沒意識到自己已經(jīng)被取代而已。 為了保證安全的讀, follower需要向leader(該leader將會執(zhí)行上面的1-3 step)請求當前最新的readindex, 然后該follower在自己本機器執(zhí)行以上的4-5 step。

alternative(二)
屏幕快照 2017-08-24 上午11.41.10.png

一旦leader的hb被集群的大多數(shù)server確定, 該leader就能假設沒有其他任何server在最小election timeout能成為leader, 這樣leader就可以延長自己的lease(這個spanner的長leader有點相似)。因此leader在這段時間內就可以回復client的讀請求而不需要和其他server交互。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容