天天看點

Redis Cluster叢集分析&部署

作者:LinkSLA智能運維管家

一、為什麼使用Redis Cluster叢集

這裡就要說到Redis叢集的演變過程

1. 主從複制

工作模式為提供多台redis服務,選擇其中的一台作為master節點向外提供讀寫服務,剩下的作為slave節點從master節點複制資料,隻向外提供讀服務。缺點在于,沒能實作redis狀态監控即故障自動切換。當主伺服器當機後,需要手動把一台伺服器切換為主伺服器,會造成一段時間内服務不可用;存儲能力受單機限制;master不能動态擴容。

2. 哨兵

哨兵模式可以實作對redis節點的監控和master的自動故障轉移。但仍然存在一些缺點。由于隻有一台master提供寫服務。當寫操作并發量很大時,無法緩解寫操作的壓力;此外master不能動态擴容。針對這種場景,Redis在3.0版本中引入了Redis Cluster叢集。

二、Redis Cluster簡介

Redis Cluster叢集是一個提供在多個Redis節點之間共享資料的程式集。由多個master節點提供寫服務,每個master節點中存儲的資料都不一樣,這些資料通過資料分片的方式被自動分割到不同的master節點上。

為了保證叢集的高可用,每個master節點下面還需要添加至少1個slave節點,這樣當某個master節點發生故障後,可以從它的slave節點中選舉一個作為新的master節點繼續提供服務。不過當某個master節點和它下面所有的slave節點都發生故障時,整個叢集就不可用了。基本架構圖如下:

三、Redis Cluster叢集的工作原理

3.1 哈希槽分區

這裡就需要提到哈希槽這個概念。

Redis Cluster叢集有16384個哈希槽,每個key通過CRC16校驗後對16384取模來決定放在哪個槽。叢集的每個master節點負責一部分hash槽。比如目前叢集有3個master節點,則:

master1節點包含0~5460号哈希槽

master2節點包含5461~10922号哈希槽

master3節點包含10923~16383号哈希槽

當需要redis叢集存放一個資料(key-value)時,redis會先對這個key進行CRC16算法,将得到的結果對16384進行取餘,這個餘數會對應到(0~16383)其中一個槽,進而決定key-value存儲在哪個節點中。

3.2 叢集通信

尋找槽的過程并非一次就能精準命中的。比如某個key經取餘計算要放到11000号槽位,但并不是一下就找到master3節點,可能先去通路master1、master2節點,再找到master3節點。

叢集中的每個節點都儲存了其它節點的資訊,包括目前叢集狀态、叢集中各節點負責的哈希槽、叢集中各節點的master-slave狀态、叢集中各節點的存活狀态等。這樣即使第一次通路未能命中槽,也會告知用戶端該槽位在哪個節點。

四、環境準備

準備八台機器,ip位址分别為192.168.8.105~112(主機名分别為node1~node8),其中192.168.8.111、192.168.8.112做Redis Cluster叢集擴容&縮容使用,另外六台機器做Redis Cluster叢集。用編譯安裝的方式部署6.2.x版本的redis。

五、搭建Redis Cluster叢集

5.1 啟用Redis Cluster配置

192.168.8.105~110六台機器需做redis.conf的如下配置(有注釋的取消注釋):

bind 0.0.0.0
dir "xxxxxxx" #快照檔案儲存路徑
masterauth xxx #建議配置,否則後期的主從複制不能成功
requirepass xxx
cluster-enabled yes #開啟叢集模式,普通模式不能加入Redis Cluster叢集。開啟後程序會有cluster辨別
cluster-config-file nodes-6379.conf #此為叢集狀态資料檔案,記錄主從關系和哈希槽範圍資訊,由Redis Cluster叢集自動建立和維護
cluster-require-full-coverage no #預設為yes,設為no可以防止一個節點不可用導緻整個Redis Cluster叢集不可用之後啟動Redis           

5.2 建立Redis Cluster叢集

在任意一台機器執行如下指令:

redis-cli -a xxxxxx --cluster
create 192.168.8.105:6379 192.168.8.106:6379 192.168.8.107:6379
192.168.8.108:6379 192.168.8.109:6379 192.168.8.110:6379 --cluster-replicas 1
#指令redis-cli --cluster的選項--cluster-replicas是指定每個主節點的從節點個數           

輸入yes自動建立叢集,确認已經配置設定的主從關系和各個master節點管理的槽位範圍

這樣Redis Cluster叢集就建立成功了。

可以用redis-cli -a xxxxxx --cluster check ip:port指令或redis-cli –a xxxxxx cluster info指令檢視Redis Cluster叢集狀态,用redis-cli –a xxxxxx cluster nodes檢視主從對應關系&槽位配置設定情況

5.3 測試Redis Cluster叢集讀寫資料

先随便進入一個master節點寫資料,發現不能寫入:

再到對應的master節點去寫資料就正常了。但是讀資料也是在相關的master節點,對應的slave節點也無法執行get k1指令,隻能用keys *指令檢視。此時可以發現,slave節點僅用來存資料,讀寫操作都做不了。

但是用redis-cli -a xxxxxx -c(-c參數用于叢集模式)可以實作自動重定向,随便進入一個master節點寫資料都可以,資料可以重定向到其它master節點

5.4 測試Redis Cluster叢集的高可用

此時的主從關系如下:

Redis Cluster叢集分析&部署

将192.168.8.105的redis服務停掉,之後由192.168.8.109提升為新的主節點(見下圖):

通過檢視叢集狀态資料檔案nodes-6379.conf也能看到192.168.8.105的redis服務異常,192.168.8.109提升為新的master節點。現由109機器代替105機器提供讀寫服務

即使重新開機105機器的redis,該機器也變成了109機器的從節點

注意:如果是105和109機器或107和108機器或106和110機器(對應的主從關系的機器)的redis同時挂掉,則它們存的資料就不能通路。如果有設定了RDB持久化,則在重新開機redis後可以從rdb檔案重新加載資料,但是在生産環境這樣也會丢失一部分資料

六、Redis Cluster叢集管理

6.1 擴容

6.1.1 應用場景

在客戶通路量激增的情況下,已有的Redis Cluster叢集很難滿足越來越高的并發通路請求。為解決此問題,就新增兩台機器,把它們動态添加到現有的Redis Cluster叢集,且不影響業務的正常通路。簡單的說就是新加n組主從到叢集中。

注意:生産環境建議master節點為奇數個(eg:3,5),以防發生腦裂現象

6.1.2 準備工作

為192.168.8.111和192.168.8.112兩台機器部署redis,配置檔案與其它六台機器的相同,之後啟動redis。

6.1.3 添加新的master節點到叢集

這裡把192.168.8.111作為新的master節點。在111機器執行如下指令:

redis-cli -a xxxxxx --cluster
add-node 192.168.8.111:6379 192.168.8.106:6379
#這裡包括以下示例中的192.168.8.106為已有Redis Cluster叢集的任意節點           

執行效果如下:

此時可以看到,雖然111機器作為新的master加入了Redis Cluster叢集,但沒有槽位,後續需要配置設定。

6.1.4 為新的master節點重新配置設定槽位

在任意一個master節點執行如下指令:

redis-cli -a xxxxxx --cluster reshard 192.168.8.106:6379           

這樣就完成配置設定槽位了。再确認一下槽位是否配置設定成功:

此時可以看到,新的master節點槽位已經配置設定成功,但沒有配置從節點,存在高可用隐患。

6.1.5 為新的master節點指定slave節點實作高可用

将192.168.8.112作為192.168.8.111機器的從節點。在112機器執行如下指令:

redis-cli -a magedu --cluster
add-node 192.168.8.112:6379 192.168.8.106:6379 --cluster-slave
--cluster-master-id 9219a29e48e0f2615f1d003714a7cd82a03ae9a1           

驗證。如果是8個節點,4組主從說明擴容成功:

此時192.168.8.112就是192.168.8.111的從節點

6.2 縮容

6.2.1 應用場景

随着業務量縮水,使用者通路量明顯下降,業務組經與上司商量後決定将現有Redis Cluster叢集的8台機器下線2台。縮容後仍能滿足目前業務需求。

6.2.2 删除節點的過程

擴容是先添加機器到叢集,再配置設定槽位。而縮容與之相反,是先将要下線的機器的槽位遷移到叢集中的其它機器,然後才能下線機器。如果一個機器上的槽位未完全轉移幹淨,删除該機器時會提示資料出錯導緻無法删除。

6.2.3 遷移要删除的master節點的槽位到其它master節點

這裡仍然用192.168.8.111和192.168.8.112進行操作。

此時主從關系如下:

Redis Cluster叢集分析&部署

根據之前的擴容操作(見相關截圖),先把0~1364号槽位移到109機器。在叢集任意一個節點執行如下指令:

redis-cli -a magedu --cluster reshard 192.168.8.106:6379           

再把5461~6826号槽位移到106機器,把10923~12287号槽位移到107機器。這樣111機器就沒有槽位了。由于112機器一開始作為111機器的從節點,無槽位,是以後續可直接執行删除機器的操作。

6.2.4 從叢集中删除機器

在叢集中任意一個節點執行如下指令:

#删除111機器
redis-cli -a magedu --cluster
del-node 192.168.8.106:6379 9219a29e48e0f2615f1d003714a7cd82a03ae9a1
#删除112機器
redis-cli -a magedu --cluster
del-node 192.168.8.106:6379 4f6306221bb9afa5ff38ea9e9df85199575b22fd           

此時再次檢視就發現111和112機器被踢出叢集了:

6.3 叢集傾斜

Redis Cluster叢集的多個節點運作了一段時間後可能會出現傾斜現象,某個節點資料偏多,記憶體消耗更大,或者通路更多。

發生傾斜的原因如下:

節點之間槽位配置設定不均

不同槽位對應的鍵值數量差異較大

記憶體相關配置不一緻

包含bigkey

熱點資料不均衡。有的資料通路量特别大,有的資料通路量特别小

相關操作包括:

#擷取指定槽位對應的key個數。這裡1000為槽位号
redis-cli -a xxxxxx cluster countkeysinslot 1000
#槽位重新平衡分布
redis-cli -a xxxxxx --cluster rebalance
192.168.8.106:6379
#擷取bigkey
redis-cli -a xxxxxx --bigkeys           

七、Redis Cluster叢集的局限性

讀寫操作均由主節點完成,從節點僅做備用

主機數量多,造成維護成本較高

一些指令不能跨節點使用:mget、keys、scan等

不支援多個資料庫,叢集模式下隻有1個資料庫

https://blog.51cto.com/u_15796303/5950859

繼續閱讀