這篇是對黃建宏的總結和學習筆記。redis
客戶端、節點一、節點2之間的關係?
1.客戶端鏈接節點1
2.客戶端發送加入集羣命令給鏈接上的節點1
Cluster meet 節點2ip 節點2port
3.節點1把節點2加入集羣
所謂加入集羣,其實也就是,給每一個節點創建一個數據結構,數據結構包含了哪些槽。算法
如何給節點添加槽?
也是客戶端——節點。
客戶端發送添加槽命令。
命令的具體格式是:addslots 槽編號。數組
細節
具體細節是客戶端發送命令到節點。命令格式以下: 1.命令 2.哪一個節點IP 3.哪一個槽數據結構
哪兩個?
1.單個節點的槽
2.全部槽負載均衡
第一種,數據結構是節點數據結構的數據(槽數組,即二進制位數組)。學習
第二種,是集羣數據結構的數據(二進制位數組)。指針
如今的問題是,爲何要搞兩種?
由於,第一種是用於節點之間互相通訊,告知對方我有哪些槽,而後對方就把你的槽保存起來。 第二種是,用於查找某一個槽是在哪個節點,本質上第一種也能夠查找到,可是須要遍歷,因此實際上。這又是一個用空間換時間的問題。cdn
所謂槽slot?就是一個bit,就是一個位,二進制。blog
傳播的目的是,使得每一個節點都保存/知道了每一個槽slot是指向哪個節點。或者叫告知別的節點,我有哪些槽,具體實現是經過命令,節點1——節點2。排序
具體實現?二進制bit位。
具體保存的數據結構是,每一個節點,包括當前節點本身,都有一個數據結構存放這些數據。
集羣是有下線和上線的狀態的:
1.下線
2.上線
不一樣狀態,只能作不一樣的事。
例如,下線的時候,你得先讓集羣上線。上線的標誌就是,全部槽分配完畢,一個都不能剩下,不然狀態字段就是下線。
上線以後,就能夠發送更多的命令了。好比,數據命令。所謂數據命令,就是寫數據啊讀數據的命令。
步驟
1.先計算Hash
2.Hash值和總槽數量進行按位與
總結
像這種負載均衡,通常都是採用Hash方法,即便不是Hash,也是在Hash的基礎之上再進行按位與運算。
注意
Redis的Hash,不是通常的Hash,而是crc,其實也是一種Hash算法,本質上都是爲了儘量地獲得一個惟一的值。
就是客戶端從某個節點讀數據的時候,發現該數據不在當前節點,這個時候就要重定向。
具體怎麼作?
固然是根據IP/port,若是錯誤,就會返回正確的IP/port,由於每一個節點都保存命了全部的槽/節點。
注意
這裏還有個問題,就是客戶端與節點的通訊。客戶端與節點的通訊,本質上都是TCP套接字創建鏈接,並且一個客戶端可能也能夠同時和多個節點鏈接/創建套接字。
若是重定向的時候,發現新的節點沒有創建鏈接,就先創建鏈接,不然就直接通訊。
即存儲key+槽+多個指針,使用的數據結構是跳躍鏈表skiplist。
跳躍鏈表的節點,包含的字段有:
1.value,即數據
這裏是key
2.score,即分數,用於排序
這裏是槽編號
3.指針,多級
整個流程
說明
有專門的功能模塊redistrib,來處理切換槽到新的節點。
槽的數據遷移完以後,其餘節點(非源節點和目標節點)怎麼知道槽已經切換節點?
經過消息。
具體一點?書上沒講清楚,這個地方。
另外,所謂的分片,就是分配槽,片就是槽,一個片就是一個槽。明明概念裏是叫槽,非要整出來一個新名詞,看着讓人煩。
集羣和哨兵是兩套不一樣的實現高可用/集羣的機制。
1.哨兵
是哨兵選leader哨兵,leader哨兵再選從節點。
2.集羣
如何判斷一個主節點是否掛了?
選舉機制/算法。
就是全部的主節點之間互相投票。
這個時候是沒有哨兵的,那麼就只能在主數據節點之間互相投票選舉,所謂投票選舉,其實就是互相兩兩之間進行投票,且只能投給一我的,哪一個得票數最早過半,就勝出。
除了沒有哨兵節點,和不是哨兵節點來選舉從數據節點之外,其餘都差很少。
可是,本質上,選舉算法是同樣的,不論是哨兵機制的哨兵內部選leader哨兵,仍是集羣機制的判斷某個主節點是否下線,仍是其餘的選舉,只要是投票選舉,而且只能選一我的,那麼就是計算最終得票數量,最早過半,就勝出。
還有一個問題,就是由誰來廣播哪一個節點下線?
由於雖然是投票,可是最終是有一個節點標記下線節點,並且這個節點須要把下線節點這個消息廣播出去。可是這個標記下線節點和廣播消息的節點,是怎麼選出來的?按id排序或者其餘什麼排序,參考哨兵機制下的選從節點。
廣播的消息,主要兩個數據:1.我已經升級成爲新的主節點 2.舊的主節點已經下線。
五種
1.拉別人加入集羣Cluster Meet
2.請求ping
3.響應pong
4.fail
5.publish
Gossip協議?
黃建宏