Redis集羣搭建及選舉原理

redis集羣簡述java

哨兵模式中若是主從中master宕機了,是經過哨兵來選舉出新的master,在這個選舉切換主從的過程,整個redis服務是不可用的。並且哨兵模式中只有一個主節點對外提供服務,所以無法支持更高的併發。並且當個主節點的內存設置也不宜過大。不然會致使持久化文件過大,影響數據恢復或主從同步的效率。node

 

redis集羣是由一系列的主從節點羣組成的分佈式服務器羣,它具備複製、高可用和分片特性。Redis集羣不須要 sentinel哨兵也能完成節點移除和故障轉移的功能。須要將每一個節點設置成集羣模式,這種集羣模式沒有中心節點,客戶端經過CRC16算法對key進行hashredis

獲得一個值,來判斷該key存儲在哪一個主從服務上面,所以就算是某一個主從整個宕機,redis集羣也是部分可用的。方便水平擴展,能夠根據業務規模能夠隨時加減配置。據官方文檔稱能夠線性擴展到上萬個節點(可是官方推薦不超過1000個節點)。redis集羣的性能和高可用性均優於哨兵模式算法

 

 

 

Redis集羣搭建緩存

 

 

 

1.修改redis.conf配置文件服務器

  1. daemonize yes                    後臺啓動   
  2. cluster-enabled yes                開啓集羣模式
  3. cluster-config-file nodes-6379.conf   集羣配置信息存放文件名
  4. cluster-node-timeout 5000          節點離線時間限制,到達此值時發起某個主從從新選舉master
  5. protected-mode no                關閉保護模式
  6. requirepass xxx                   設置本機密碼
  7. masterauth xxx                    設置訪問別的機器的密碼

2.注意關閉服務器的防火牆,不然可能形成節點之間沒法通訊,沒法搭建集羣網絡

使用修改好的配置文件啓動redis服務,我這裏使用三個一主一歷來搭建。所以先將6redis服務使用指定的配置文件redis-master.conf啓動起來:src/redis-server redis-master.conf併發

3.搭建集羣服務dom

爲了保險起見最好先檢查下每臺機器的redis服務是否正常啓動了ps -ef|grep redis分佈式

能夠看見redis服務進程後面有個cluster的標誌,普通啓動的redis服務是沒有這個標誌的

 

 

5.0版本能夠直接使用C語言客戶端提供的指令去構建集羣:

src/redis-cli -a xxx --cluster create --cluster-replicas 1 192.168.0.67:6379 192.168.0.68:6379 192.168.0.69:6379 192.168.0.70:6379 192.168.0.71:6379 192.168.0.72:6379

-a  配置的密碼

--cluster create  表示集羣建立

--cluster-replicas   表示每一個master幾個slave,上面一共6redis節點,所以會構建三個一主一從。

 

執行命令以前,若是你的redis環境之前搭建過主從或者哨兵之類的,數據不乾淨可能會報錯,最好將持久化文件刪掉,而後flushdb,將之前髒數據清理掉,不然可能出現以下錯誤:

 

 

 正常執行會返回一個集羣分配計劃,咱們按照它的計劃便可:

 

 

 

 

 

 而後節點之間就開始通訊構建集羣,最後會看見16384slots分配完畢,能夠看見構建計劃中有三個master,每一個master都是有指定槽位的。意思就是存入的key通過crc16 hash算法以後獲得的值,在哪一個範圍內,就存儲到那個redis主從上面去,這就是redis的分片集羣模式。

 

 至此集羣搭建完畢

4.集羣操做

以集羣方式鏈接redis客戶端經過cluster info查看集羣信息,經過cluster nodes查看節點信息

src/redis-cli -a 密碼 -c   集羣方式鏈接

 

 咱們設置set abc 123一個值 會看見客戶點會計算abcslot7638, 而後重定向到對應的主從的master上面去寫數據

 

 如今我看下java客戶端的jedis裏面的key值計算redis.clients.util.JedisClusterCRC16#getSlot(java.lang.String)

 

 

 

最後計算結果就會落到0-16383之間去。

Redis Cluster 的客戶端來鏈接集羣時,它也會獲得一份集羣的槽位配置信息並將其緩存在客戶端本地。這樣當客戶 端要查找某個 key 時,能夠直接定位到目標節點。同時由於槽位的信息可能會存在客戶端與服務器不一致的狀況,還需 要糾正機制來實現槽位信息的校驗調整。

 

 

集中式集羣和分片式集羣

Redis節點之間使用的是gossip協議進行通訊,每一個節點之間都會互相通訊。

 

gossip協議包含多種消息,包括pingpongmeetfail等等。

 

ping:每一個節點都會頻繁給其餘節點發送ping,其中包含本身的狀態還有本身維護的集羣元數據,互相經過ping交換元數據;

 

pong: 返回pingmeet,包含本身的狀態和其餘信息,也能夠用於信息廣播和更新;

 

fail: 某個節點判斷另外一個節點fail以後,就發送fail給其餘節點,通知其餘節點,指定的節點宕機了。

 

meet:某個節點發送meet給新加入的節點,讓新節點加入集羣中,而後新節點就會開始與其餘節點進行通訊,不須要發送造成網絡的所需的全部CLUSTER MEET命令。發送CLUSTER MEET消息以便每一個節點可以達到其餘每一個節點只需通 過一條已知的節點鏈就夠了。因爲在心跳包中會交換gossip信息,將會建立節點間缺失的連接。

 

 

 

gossip協議的優勢在於元數據的更新比較分散,不是集中在一個地方,更新請求會陸陸續續,打到全部節點上去更新, 有必定的延時,下降了壓力;缺點在於元數據更新有延時可能致使集羣的一些操做會有一些滯後。

 

就是本身提供服務的端口號+10000,好比6379,那麼用於節點間通訊 的就是16379端口。 每一個節點每隔一段時間都會往另外幾個節點發送ping消息,同時其餘幾點接收到ping消息以後返回pong消息。

 

 

 

還有就是集中式的,好比ZK集羣

 

集中式的有點在於數據的更新和讀取,時效性很是好,一旦元數據出現變動當即就會更新到集中式(master)的存儲中,其餘節點讀取的 時候當即就能夠當即感知到;不足在於全部的元數據的更新壓力所有集中在一個地方,可能致使元數據的存儲壓力。

 

 

 

 

Redis集羣選舉機制

 

slave發現本身的master變爲FAIL狀態時,便嘗試發起選舉,以期成爲新的master。因爲掛掉的master可能會有多個slave,從而存在多個slave競爭成爲master節點的過程, 其過程以下:

 

1.slave發現本身的master變爲FAIL

 

2.將本身記錄的集羣currentEpoch(選舉輪次標記)加1,並廣播信息給集羣中其餘節點

 

3.其餘節點收到該信息,只有master響應,判斷請求者的合法性,併發送結果

 

4.嘗試選舉的slave收集master返回的結果,收到超過半數master的統一後變成新Master

 

5.廣播Pong消息通知其餘集羣節點。

 

若是此次選舉不成功,好比三個小的主從A,B,C組成的集羣,A的master掛了,A的兩個小弟發起選舉,結果B的master投給A的小弟A1,C的master投給了A的小弟A2,這樣就會發起第二次選舉,選舉輪次標記+1繼續上面的流程。事實上從節點並非在主節點一進入 FAIL 狀態就立刻嘗試發起選舉,而是有必定延遲,必定的延遲確保咱們等待FAIL狀態在集羣中傳播,slave若是當即嘗試選舉,其它masters或許還沒有意識到FAIL狀態,可能會拒絕投票。 同時下面公式裏面的隨機數,也能夠有效避免slave同時發起選舉,致使的平票狀況。

 

•延遲計算公式:

 

DELAY = 500ms + random(0 ~ 500ms) + SLAVE_RANK * 1000ms

 

•SLAVE_RANK表示此slave已經從master複製數據的總量的rank。Rank越小表明已複製的數據越新。這種方式下,持有最新數據的slave將會首先發起選舉(理論上)。

 

 

 

前面說到這種分片的集羣模式的集羣能夠部分提供服務,redis.conf的配置cluster-require-full-coverage爲no時,表示當一個小主從總體掛掉的時候集羣也能夠用,也是說0-16383個槽位中,落在該主從對應的slots上面的key是用不了的,可是若是key落在其餘的範圍是仍然可用的。

相關文章
相關標籤/搜索