前言
在巨量資料下,資料庫合理的分片(DB sharding)可以幫助我們承受更高量的資料量(前提Index還有設定都調教到很好在考慮 sharding)
而在 Redis 世界裡也有 redis cluster 來做 sharding 事情,今天就來跟大家分享介紹
我使用是 bitnami redis-cluster 這個 Image 來做這次 Poc
此案例是 3 master - 3 slave Redis server 範例
建立 Redis Cluster
How to Use
1 | docker-compose up -d |
跑完之後就會出現 6 台 Redis Container,如下表
1 | $ docker ps |
查看 Redis Cluster 架構
我們進入 rediscluster_redis-node-0_1
這台Container 利用 redis-cli 輸入 CLUSTER INFO
可以查看目前 Cluster 基本狀態
1 | $ docker exec -it rediscluster_redis-node-0_1 bash |
本篇我 redis password 統一使用
redisCluster
所以進入 redis 操作之前記得輸入-a
跟密碼
進入可以看到幾個重要資訊
- cluster_state
- cluster_size:3
- cluster_current_epoch:6
- cluster_slots_assigned
代表目前 Cluster 啟動狀態OK,再來我們利用 --cluster check
了解該 Redis Server Cluster 中 master-slave 跟各節點對應關係
1 | redis-cli --cluster check 127.0.0.1:6379 -a redisCluster |
結果如下
1 | /$ redis-cli --cluster check 172.22.0.3:6379 -a redisCluster |
依照上面資訊我們可以畫出架構如圖
Master 1 => slave 1 = 172.22.0.2 => 172.22.0.3
Master 2 => slave 2 = 172.22.0.5 => 172.22.0.7
Master 3 => slave 3 = 172.22.0.4 => 172.22.0.6
redis 幫我們分配 master 對應 slave 並沒有特別順序,所以你建立的跟我建立很可能不一樣
我們可以在透過下面命令顯示 container 對應使用 ip
1 | $ docker inspect -f '{{.Name}} - {{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $(docker ps -q) |
使用上面命令可以更好理解,Container Name之間對應關係
在 Redis Clsuter 新增 key 注意事項
我進入其中一台 master container rediscluster_redis-node-0_1
1 | /$ redis-cli -h 172.22.0.2 -a redisCluster |
使用 get
拿資料時發現我們只拿的到 k2,k3
的資料
1 | 172.22.0.2:6379> get k1 |
我們可以透過 CLUSTER KEYSLOT {key}
來算出我們 key 算出來的 slot 數值
1 | 172.22.0.2:6379> CLUSTER KEYSLOT k1 |
因為我們是進入 172.22.0.2
這台 Redis server 操作 我們只能操作屬於我們 slot 也就是介於 [0-5460]
slot 資料,所以只有 k2,k3
符合
那你會想這樣不就跟單機操作一樣,別急讓我來說怎麼正確使用 Redis Cluster
我們先退出當前 redis-cli 操作 redis-cli -h 172.22.0.2 -a redisCluster -c
在此輸入並在最後多一個參數 -c
-c
代表是要使用 cluster 操作
在執行 set {key} {value}
命令,會發現已經沒有 error 但取而代之是 Redirected to slot
那是因為 -c
模式下會幫我們在資料寫入前轉到該 slot redis server node 中在執行命令.
所以能發現出現 Redirected to slot
Redis server ip 就會改變
1 | /$ redis-cli -h 172.22.0.2 -a redisCluster -c |
所以在操作 Redis cluster 記得要使用 cluster 操作模式
擴充 Redis Cluster
假如因為業務需求流量突然進來我們想在目前 Cluster 多開幾組 master-slave redis 怎辦?
這邊跟大家來分享如何多加 redis 進入 Cluster 中
擴充步驟
- 在 redis-cluster 中新增多組(或一組) master-slave redis
- 將新建立 master container 加入 Cluster 中
- 把目前 Cluster slot 分配給 剛建立 master container (如果可以最好 slot 數量平均)
- 將新建立 slave container 掛入新建立 master container 上
在 redis-cluster 中新增多組(或一組) master-slave redis,使用下面命令
因為在使用 docker-compose 啟動時已經幫我們建立一個 network 所以我們需要指定新加的兩個 Container 在
rediscluster_default
中這樣他們才可以訪問的到
1 | docker run -d --name redis-new-master01 --network rediscluster_default --privileged=true -p 8106:6379 redis:6.2 --cluster-enabled yes --appendonly yes --requirepass "redisCluster" |
在利用 docker ps
我們發現剛建立的兩個 Container 已經建立完畢
1 | CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES |
查詢到 redis-new-master01
使用 IP 我們可以利用 --cluster add-node
將新的 master node 加入 cluster 中
1 | redis-cli --cluster add-node 172.22.0.8:6379 172.22.0.2:6379 -a redisCluster |
加入成功後我們在利用 --cluster check
命令查詢 Cluster 資訊,會看到目前多了一筆資料 172.22.0.8:6379 (0885f85b...) -> 0 keys | 0 slots | 0 slaves.
下一步就需要分配 slot 給這個 master
1 | /$ redis-cli --cluster check 172.22.0.3:6379 -a redisCluster |
目前要做的是把當前 Cluster 上 master 上的 slot 分配給,剛建立 master container,達到資料分擔
我們可以透過 redis-cli --cluster reshard {被分配 Redis Cluster 節點 IP}
,由上面資訊得知新建立 master id 是 172.22.0.8:6379
1 | redis-cli --cluster reshard 172.22.0.8:6379 -a redisCluster |
執行後我們會被詢問要轉移多少 slot 數量給新的 master,我們知道 Redis Cluster 有 16384 個 slot 所以為了平均分配 16384/4 = 4096
How many slots do you want to move (from 1 to 16384)
我們可以輸入4096
What is the receiving node ID?
我們由上面資訊知道 新建立 master id 是0885f85b94f8ddc186f1eac8f532be532fb7f5b1
最後可以輸入 all
就會開始分配 slot
1 | Please enter all the source node IDs. |
跑完後我們利用 redis-cli --cluster check 172.22.0.8:6379 -a redisCluster
查詢可以看到 slot 已經平均分配到四個 master 上面了
1 | 172.22.0.8:6379 (0885f85b...) -> 1 keys | 4096 slots | 0 slaves. |
最後一步就是把 新的 slave redis 掛載到剛剛的 master redis 上
我們可以利用下面命令 template 來處理
1 | redis-cli --cluster add-node {new-slave-redis IP} {cluster-redis IP} --cluster-slave --cluster-master-id 新節點master-id -a redisCluster |
轉換成可執行命令如下
1 | redis-cli --cluster add-node 172.22.0.9:6379 172.22.0.8:6379 --cluster-slave --cluster-master-id 0885f85b94f8ddc186f1eac8f532be532fb7f5b1 -a redisCluster |
看到下面執行結果代表掛載成功
1 | //... |
全部執行完後結果,我們就有四個節點可以存放 Redis 資料
處理完後 Redis Cluster 架構圖就如下
cluster rebalance 命令
假如我們原本想要平均分配每個 master node slot 數量,但不小心設定錯誤可以使用 --cluster rebalance
來重新分配 slot 數量,讓每個 master 得到平衡的 slot 數量
1 | redis-cli --cluster rebalance 172.21.0.8:6379 -a redisCluster |
縮容 Redis Cluster
縮容 Redis Cluster 也有相對應步驟,步驟跟擴容相反步驟
- 將 slave Redis container 移除 Cluster 並刪除
- 清出 master Redis container slot 數量並重新分配 (確保此 master Redis 沒有對應 slot )
- 刪除 master Redis container slot
本次目標要把 Master1-Slave1
移除 Cluster
將slave Redis container 移除 Cluster 並刪除,我們可以執行下面命令
1 | redis-cli --cluster del-node {要刪除的 Redis IP} {要刪除的 Redis ID} -a redisCluster |
在刪除前先查看資訊 Cluster 資訊
1 | /$ redis-cli --cluster check 172.22.0.4:6379 -a redisCluster |
確認要刪除 Redis 資訊是 172.22.0.3:6379
跟 2c25a1a5d1cb1ba780170685c4f39dfe6f0da8f0
1 | /$ redis-cli --cluster del-node 172.22.0.3:6379 2c25a1a5d1cb1ba780170685c4f39dfe6f0da8f0 -a redisCluster |
刪除 slave1 之後能發現 master1 原本對應的 slave 已經不見了
這次轉移 master slot 我使用 reshard
另一種寫法
1 | redis-cli --cluster reshard 172.22.0.2:6379 \ |
執行完後發現到 172.22.0.2:6379 身上已經沒有其他 Slot 了,之後可以利用上面說到 rebalance
命令來重新分配 slot
1 | redis-cli --cluster rebalance 172.22.0.4:6379 -a redisCluster |
分配完後結果如上
最後我們就可以執行最後一步:刪除 master redis 使用 --cluster del-node
命令即可
1 | redis-cli --cluster del-node 172.22.0.2:6379 3decf740935f98a40d2d73416937e63abc3f4781 -a redisCluster |
刪除後結果如上,在 Cluster 已經看不到 master1 蹤影了
小結
Redis 官方對於 Cluster 支援還有說明文件寫得很棒,推薦大家去看
如果會有 Redis 為何使用 16384 當作 slot 數量可以參考作者回答的資料 why redis-cluster use 16384 slots
參考資料
cluster-spec
Redis cluster tutorial
此文作者:Daniel Shih(石頭)
此文地址: https://isdaniel.github.io/redis-cluster-introduce-01/
版權聲明:本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 3.0 TW 許可協議。轉載請註明出處!