天天看點

一起raft 切主後的故障分析現象問題分析謎底揭曉教訓參考連結

現象

線上由3個控制節點組成的一個raft叢集中的一個節點stop了,stop 之前剛發過一條踢掉一台資料節點的指令,但是資料節點并沒完全被踢掉---雖然中繼資料不在了,但是節點還在叢集中,前端還能通路它。

問題分析

梳理了下kick 資料節點的業務流程如下:

1.RPC伺服器端響應brpc請求;
2.伺服器端判斷目前如果是leader, 就進入leader 處理流程;
3.leader append KickDataServer 事務日志到所有的副本;
4. 每個副本收到事務日志,走下邊的流程:
4.1 解析對應的請求類型;
4.2 判斷自己現在角色是否leader, 如果不是結束目前流程;如果是,開始apply 這條事務日志:
4.2.1 去掉資料庫中關于待kick的資料節點的記錄;
4.2.2 針對有副本在待删除節點機器上的block, 發起補副本;
4.2.3 傳回給CLI kick資料節點成功;
4.2.4 給待kick的資料節點發下線指令。
           

上面流程看了兩遍,初步懷疑是執行到4.2.3後碰到控制節點被stop 導緻的。但後來仔細一下,咱這是基于raft的啊,即便老leader被stop掉,新leader 接管後,也會重放踢資料節點的指令啊? 那問題在哪呢?

謎底揭曉

把重複踢資料節點的流程代碼又看了一遍,發現其在發起補副本之前會有個檢查:

檢查待踢的節點是否還在資料庫可用節點清單裡,如果在才繼續往下走,如果不在就結束目前流程。到這裡才恍然大悟,原來這裡問題的症結在于上面流程中:

4.2.1 去掉資料庫中關于待kick的資料節點的記錄;
........
4.2.4 給待kick的資料節點發下線指令。
           

資料沒下線完就提前把這個節點從資料庫裡去掉了。這樣apply的時候按照上面的流程,當然不會再真正的去幹活了。

教訓

參考連結