1. 問題
1) redis 集羣如果一個主節點掛了,會怎麼處理
2) redis集羣如果一個從節點掛了,會怎麼處理
3) 如何判斷整個redis集羣掛了?
2. 處理
2.1 redis 集羣如果一個主節點掛了,會怎麼處理
在瞭解這個問題之前,我們需要知道redis集羣如何判斷一個主節點掛了?
1) 集羣中的每個節點都會頂起地向集羣中的其他節點發送PING消息
2) 默認每隔1s中發送一次PING
3) 默認隨機選擇5個集羣中的其他主節點,規則爲最長時間未PING以及PONG時間超過timeout/2
4) 如果發送PING的主節點1,在timeout時間內沒收到主節點2的PONG消息,那麼主節點1會將主節點2的狀態標記爲pfail
5)主節點1在後續發送PING消息時,會帶上主節點2的pfail狀態,收到這個消息的主節點會在clusterNode裏下線報告fail_reports中將主節點2標記爲pfail
6) 當某個主節點被標記爲pfail的個數大於集羣總主節點個數的一半時,會被標記爲fail, 並向整個集羣廣播一條PONG消息,說明該主節點下線。
7) 其他主節點收到廣播消息後,將該主節點狀態標記爲fail,
8) 集羣進入故障轉移階段
故障轉移
1) 當一個從節點發現自己正在複製的從節點進入已下線狀態時,從節點將開始對下線主節點進行故障轉移
2) 複製下線主節點的所有從節點裏面,會有一個從節點被選爲新的主節點
3) 新的主節點從撤銷所有已下線主節點的槽位指派,並將這些槽位指給自己
4) 新的主節點會向集羣廣播一條PONG消息,告知其他節點自己已由從節點轉爲主節點,並接管相應的槽位
5) 故障轉移完成
選舉新的主節點
1) 集羣的紀元時一個自增的計數器,初始值爲0
2) 當集羣裏的某個節點開始一次故障轉移操作時,集羣的紀元會加一
3) 對於每個紀元,集羣裏每個複製處理槽位的主節點都有一次投票機會,而第一次向主節點要求投票的從節點將獲得主節點的投票
4) 什麼時候開始投票? 當從節點發現自己正在複製的主節點進入已下線狀態,從節點會向集羣廣播一條CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST消息,收到該消息的主節點可以開始投票
5) 主節點投票後返回CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息
6) 當某個從節點的票數大於投票總節點數的一半時,被選爲新的主節點
7) 若每個獲得足夠的票數,進入下一輪投票
2.2 redis集羣如果一個從節點掛了,會怎麼處理
2.3 如何判斷整個redis集羣掛了?
超過一般的主節點處於fail狀態
3. 原理
整個集羣的節點
clusterState.nodes字典中
key: node_id
value: 該節點對應的clusterNode
從節點的結構
struct clusterNode {
struct clusterNode *slaveof; // 如果時從節點,那麼會指向主節點
}