Redis 學習筆記(十四)Redis Cluster介紹與搭建
Redis Cluster 介紹與搭建
1. Redis Cluster介紹
Redis Cluster
是Redis
的分散式解決方案,在Redis 3.0
版本正式推出的,有效解決了Redis
分散式方面的需求。當遇到單機記憶體、併發、流量等瓶頸時,可以採用Cluster
架構達到負載均衡的目的。
1.1 資料分佈理論
分散式資料庫首要解決把整個資料集按照分割槽規則對映到多個節點的問題,即把資料集劃分到多個節點上,每個節點負責整個資料的一個子集。常見的分割槽規則有雜湊分割槽和順序分割槽。Redis Cluster
採用雜湊分割槽規則,因此接下來會討論雜湊分割槽規則。常見的雜湊分割槽有以下幾種:
- 節點取餘分割槽
- 一致性雜湊分割槽
- 虛擬槽分割槽
Redis Cluster
採用虛擬槽分割槽,因此先介紹一下虛擬槽分割槽。
虛擬槽分割槽巧妙地使用了雜湊空間,使用分散度良好的雜湊函式把所有的資料對映到一個固定範圍內的整數集合,整數定義為槽(slot)。比如Redis Cluster
槽的範圍是0 ~ 16383
。槽是叢集內資料管理和遷移的基本單位。採用大範圍的槽的主要目的是為了方便資料的拆分和叢集的擴充套件,每個節點負責一定數量的槽。
1.2 Redis 資料分割槽
Redis Cluster
採用虛擬槽分割槽,所有的鍵根據雜湊函式對映到0 ~ 16383
,計算公式:slot = CRC16(key)&16383
下圖展現一個五個節點構成的叢集,每個節點平均大約負責3276
個槽,以及通過計算公式對映到對應節點的對應槽的過程。
Redis
虛擬槽分割槽的特定:
- 解耦資料和節點之間的關係,簡化了節點擴容和收縮難度。
- 節點自身維護槽的對映關係,不需要客戶端或者代理服務維護槽分割槽元資料。
- 支援節點、槽、鍵之間的對映查詢,用於資料路由、線上伸縮等場景。
1.3 Redis 叢集功能限制
Redis
叢集相對單機在功能上有一定限制。
key
批量操作支援有限。如:MSET``MGET
,目前只支援具有相同slot
值的key執行批量操作。key
事務操作支援有限。支援多key
key
作為資料分割槽的最小粒度,因此不能將一個大的鍵值物件對映到不同的節點。如:hash
、list
。- 不支援多資料庫空間。單機下
Redis
支援16
個數據庫,叢集模式下只能使用一個數據庫空間,即db 0
。 - 複製結構只支援一層,不支援巢狀樹狀複製結構。
2. 搭建 Redis Cluster
搭建叢集工作分為三步:
- 準備節點
- 節點握手
- 分配槽
2.1 準備節點
Redis
叢集一般由多個節點組成,節點數量為6
個才能保證組成完整高可用的叢集。下面給出一個節點的配置,其他的節點和該節點只是埠不同。
port 6379 //埠
cluster-enabled yes //開啟叢集模式
cluster-config-file nodes-6379.conf //叢集內部的配置檔案
cluster-node-timeout 15000 //節點超時時間,單位毫秒
// 其他配置和單機模式相同
啟動所有的節點
sudo redis-server conf/redis-6384.conf
sudo redis-server conf/redis-6383.conf
sudo redis-server conf/redis-6382.conf
sudo redis-server conf/redis-6381.conf
sudo redis-server conf/redis-6380.conf
sudo redis-server conf/redis-6379.conf
可以檢視日誌檔案
cat log/redis-6379.log
13103:M 30 May 15:02:09.577 * DB loaded from disk: 0.000 seconds
13103:M 30 May 15:02:09.578 * The server is now ready to accept connections on port 6379
有日誌檔案可得,節點已經啟動成功。這個日誌檔案是Redis
伺服器普通的日誌檔案,在叢集模式下,第一次也會自動建立一個日誌檔案,由配置檔案cluster-config-file
指定檔案。
叢集配置檔案的作用:當叢集內節點發生資訊變化時,如新增節點、節點下線、故障轉移等。節點會自動儲存叢集的狀態到配置檔案中。該配置檔案由Redis
自行維護,不要手動修改,防止節點重啟時產生叢集資訊錯亂。
我們來檢視一下,叢集模式的日誌檔案:
cat nodes-6379.conf
29978c0169ecc0a9054de7f4142155c1ab70258b :0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0
也可以通過客戶端連線該節點,通過命令CLUSTER NODES
來檢視:
127.0.0.1:6379> CLUSTER NODES
29978c0169ecc0a9054de7f4142155c1ab70258b :6379 myself,master - 0 0 0 connected
2.2 節點握手
節點握手是指一批執行在叢集模式的節點通過Gossip
協議彼此通訊,達到感知對方的過程。節點握手是叢集彼此通訊的第一步,由客戶端發起命令:cluster meet <ip> <port>
127.0.0.1:6379> CLUSTER MEET 127.0.0.1 6380
OK
// 傳送CLUSTER NODES可以檢視到已經感知到 6380 埠的節點了。
127.0.0.1:6379> CLUSTER NODES
29978c0169ecc0a9054de7f4142155c1ab70258b 127.0.0.1:6379 myself,master - 0 0 1 connected
8f285670923d4f1c599ecc93367c95a30fb8bf34 127.0.0.1:6380 master - 0 1496129041442 0 connected
讓所有的節點都互相感知:
127.0.0.1:6379> CLUSTER MEET 127.0.0.1 6381
OK
127.0.0.1:6379> CLUSTER MEET 127.0.0.1 6382
OK
127.0.0.1:6379> CLUSTER MEET 127.0.0.1 6383
OK
127.0.0.1:6379> CLUSTER MEET 127.0.0.1 6384
OK
// 已經全部感知到所有的節點
127.0.0.1:6379> CLUSTER NODES
e0c7961a1b07ab655bc31d8dfd583da565ec167d 127.0.0.1:6384 master - 0 1496129143703 0 connected
961097d6be64ebd2fd739ff719e97565a8cee7b5 127.0.0.1:6382 master - 0 1496129141678 0 connected
29978c0169ecc0a9054de7f4142155c1ab70258b 127.0.0.1:6379 myself,master - 0 0 1 connected
8f285670923d4f1c599ecc93367c95a30fb8bf34 127.0.0.1:6380 master - 0 1496129142682 3 connected
6fb7dfdb6188a9fe53c48ea32d541724f36434e9 127.0.0.1:6383 master - 0 1496129145699 4 connected
66478bda726ae6ba4e8fb55034d8e5e5804223ff 127.0.0.1:6381 master - 0 1496129147704 2 connected
當前已經使這六個節點組成叢集,但是現在還無法工作,因為叢集節點還沒有分配槽(slot)。
2.3 分配槽
可以看一下6379
埠的槽個數
127.0.0.1:6379> CLUSTER INFO
cluster_state:fail
cluster_slots_assigned:0 // 被分配槽的個數為0
cluster_slots_ok:0
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:0
cluster_current_epoch:5
cluster_my_epoch:1
cluster_stats_messages_sent:479
cluster_stats_messages_received:479
接下來為節點分配槽空間。通過cluster addslots
命令。
redis-cli -h 127.0.0.1 -p 6379 cluster addslots {0..5461}
OK
redis-cli -h 127.0.0.1 -p 6380 cluster addslots {5462..10922}
OK
redis-cli -h 127.0.0.1 -p 6381 cluster addslots {10923..16383}
OK
我們將16383
個槽平均分配給6379
、6380
、6381
埠的節點。再次執行CLUSTER INFO
檢視一下叢集的狀態:
127.0.0.1:6379> CLUSTER INFO
cluster_state:ok // 叢集狀態OK
cluster_slots_assigned:16384 // 已經分配了所有的槽
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:5
cluster_my_epoch:1
cluster_stats_messages_sent:1212
cluster_stats_messages_received:1212
可以通過CLUSTER NODES
來檢視分配情況:
127.0.0.1:6379> CLUSTER NODES
e0c7961a1b07ab655bc31d8dfd583da565ec167d 127.0.0.1:6384 master - 0 1496129666347 0 connected
961097d6be64ebd2fd739ff719e97565a8cee7b5 127.0.0.1:6382 master - 0 1496129664844 5 connected
29978c0169ecc0a9054de7f4142155c1ab70258b 127.0.0.1:6379 myself,master - 0 0 1 connected 0-5461
8f285670923d4f1c599ecc93367c95a30fb8bf34 127.0.0.1:6380 master - 0 1496129665846 3 connected 5462-10922
6fb7dfdb6188a9fe53c48ea32d541724f36434e9 127.0.0.1:6383 master - 0 1496129661838 4 connected
66478bda726ae6ba4e8fb55034d8e5e5804223ff 127.0.0.1:6381 master - 0 1496129666848 2 connected 10923-16383
目前還有三個節點沒有使用,作為一個完整的叢集,每個負責處理槽的節點應該具有從節點,保證當主節點出現故障時,可以自動進行故障轉移。叢集模式下,首次啟動的節點和被分配槽的節點都是主節點,從節點負責複製主節點槽的資訊和相關資料。
使用cluster replicate <nodeid>
在從節點上執行。
redis-cli -h 127.0.0.1 -p 6382 cluster replicate 29978c0169ecc0a9054de7f4142155c1ab70258b
OK
redis-cli -h 127.0.0.1 -p 6383 cluster replicate 8f285670923d4f1c599ecc93367c95a30fb8bf34
OK
redis-cli -h 127.0.0.1 -p 6384 cluster replicate 66478bda726ae6ba4e8fb55034d8e5e5804223ff
OK
通過CLUSTER NODES
可以檢視叢集節點的狀態
127.0.0.1:6379> CLUSTER NODES
e0c7961a1b07ab655bc31d8dfd583da565ec167d 127.0.0.1:6384 slave 66478bda726ae6ba4e8fb55034d8e5e5804223ff 0 1496130082754 2 connected
961097d6be64ebd2fd739ff719e97565a8cee7b5 127.0.0.1:6382 slave 29978c0169ecc0a9054de7f4142155c1ab70258b 0 1496130080749 5 connected
29978c0169ecc0a9054de7f4142155c1ab70258b 127.0.0.1:6379 myself,master - 0 0 1 connected 0-5461
8f285670923d4f1c599ecc93367c95a30fb8bf34 127.0.0.1:6380 master - 0 1496130078744 3 connected 5462-10922
6fb7dfdb6188a9fe53c48ea32d541724f36434e9 127.0.0.1:6383 slave 8f285670923d4f1c599ecc93367c95a30fb8bf34 0 1496130079747 4 connected
66478bda726ae6ba4e8fb55034d8e5e5804223ff 127.0.0.1:6381 master - 0 1496130081751 2 connected 10923-16383
這樣就完成了一個3
主3
從的Redis
叢集搭建。如下圖所示:
本文參考:《Redis開發與運維》