概述
使用哈希槽分區,6臺機器,1主1從。
一、節點搭建
使用docker創建6個redis容器,如果有6臺主機也是一樣的。
現在我們又6臺機器分別是:
主機名 | IP | 端口 |
---|---|---|
redis-node-1 | 192.168.78.100 | 6381 |
redis-node-2 | 192.168.78.100 | 6382 |
redis-node-3 | 192.168.78.100 | 6383 |
redis-node-4 | 192.168.78.100 | 6384 |
redis-node-5 | 192.168.78.100 | 6385 |
redis-node-6 | 192.168.78.100 | 6386 |
下面是創建腳本:
docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis --cluster-enabled yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis --cluster-enabled yes --appendonly yes --port 6382
docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis --cluster-enabled yes --appendonly yes --port 6383
docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis --cluster-enabled yes --appendonly yes --port 6384
docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis --cluster-enabled yes --appendonly yes --port 6385
docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis --cluster-enabled yes --appendonly yes --port 6386
如果是多臺機器的,只需要在不同的機器上執行一次創建就可以了,這需要創建6個節點就行。
二、構建哈希槽分區
然後在任意一個節點執行以下腳本,構建哈希槽分區。
# 進入容器
docker exec -it redis-node-1 /bin/bash
# 構建哈希槽分區
redis-cli --cluster create 192.168.78.100:6381 192.168.78.100:6382 192.168.78.100:6383 192.168.78.100:6384 192.168.78.100:6385 192.168.78.100:6386 --cluster-replicas 1
cluster-replicas 1
表示爲每個master節點創建1個從節點。
根據構建輸出的日誌,我們可得出:
主節點 | 從節點 | 哈希槽 |
---|---|---|
192.168.78.100:6381 | 192.168.78.100:6385 | 0 - 5460 |
192.168.78.100:6382 | 192.168.78.100:6386 | 5461 - 10922 |
192.168.78.100:6383 | 192.168.78.100:6384 | 10923 - 16383 |
在存儲數據時,根據key計算出存儲在對應的哈希槽,然後存儲到對應的主節點,從節點再從主節點同步數據。
我們可以進入redis客戶端,執行以下命令查詢槽點和節點的信息:
# 打開客戶端
redis-cli -p 6381
# 查看槽分區信息
cluster info
# 查看節點信息
cluster nodes
三、數據存儲
在存儲數據時,需要使用 -c
表示集羣模式,否則根據key計算槽點,發現不屬於該節點上的槽點時會出錯。
下面k1計算出的槽點就不在6381這個節點上,所以就發生了錯誤。
root@localhost:/data# redis-cli -p 6381
127.0.0.1:6381> set k1 v1
(error) MOVED 12706 192.168.78.100:6383
127.0.0.1:6381> set k2 v2
OK
127.0.0.1:6381> set k3 v3
OK
127.0.0.1:6381>
如果我們在啓動客戶端指定集羣模式,保存k1
時,redis就會自動給我們把數據保存到6383
這個節點上去。
root@localhost:/data# redis-cli -p 6381 -c
127.0.0.1:6381> set k1 v1
-> Redirected to slot [12706] located at 192.168.78.100:6383
OK
192.168.78.100:6383> set k2 v2
-> Redirected to slot [449] located at 192.168.78.100:6381
OK
192.168.78.100:6381> set k3 v3
OK
192.168.78.100:6381> set k4 v4
-> Redirected to slot [8455] located at 192.168.78.100:6382
OK
192.168.78.100:6382>
使用以下命令,可查看集羣存儲key的分佈情況:
redis-cli --cluster check 192.168.78.100:6381
從上圖看看出,6381節點存儲了2個key,6382和6383分別存儲了一個key。
四、主從切換
假設6381
這個節點宕機了,6381
對應的從節點6385
節點就會升級爲主節點。
# 停止6381節點
docker stop redis-node-1
此時,進入redis-node-2 6382
節點,查看節點的情況
# 進入容器
docker exec -it redis-node-2 /bin/bash
# 打開redis客戶端
redis-cli -p 6382 -c
# 查看節點狀態
cluster nodes
此時可以看出,6381處於fail狀態,6385
變成了master,然後獲取之前存儲的數據,數據正常取出。
在6381
恢復後,會變爲從節點,如果需要恢復爲主節點,可以把6385
停掉一下,讓6381
變成主節點,再啓動6385
節點,這樣就恢復原狀了。
五、集羣的擴容
現在添加2臺機器,組成一主一從,添加到之前的集羣中。
在docker中創建2個容器:
docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis --cluster-enabled yes --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis --cluster-enabled yes --appendonly yes --port 6388
進入6387
這臺機器,使用redis-cli把節點添加到集羣中:
# 進入容器
docker exec -it redis-node-7 /bin/bash
# 添加節點到集羣,需要指定集羣中的任意一個主節點,用於獲取集羣信息,此處指定6381節點
redis-cli --cluster add-node 192.168.78.100:6387 192.168.78.100:6381
此時節點就添加成功,此時檢查6387
節點信息,可看到節點已存在,只是沒有key和槽點。
redis-cli --cluster check 192.168.78.100:6387
在添加節點後需要進行重新分配槽點,不然6387
沒有槽點,沒法正常存儲數據。
進入任意一臺主節點,此處爲6381
這個主節點,然後執行重新分配槽點:
# 進入容器
docker exec -it redis-node-1 /bin/bash
# 重新分配槽點
redis-cli --cluster reshard 192.168.78.100:6381
再輸入對應的參數後,redis就會從其他節點上勻未使用的槽點過來,然後再次檢查一下節點信息:
redis-cli --cluster check 192.168.78.100:6387
此時,6387
節點也有了槽點。
最後再把6388
節點分配爲6387
的從節點,就完成集羣的擴容了。
redis-cli --cluster add-node 192.168.78.100:6388 192.168.78.100:6387 --cluster-slave --cluster-master-id 156f002af4e395f547f0262c5db2b54e634a1fda
cluster-master-id 就是6387節點的ID。
此時查看集羣情況:
cluster nodes
此時集羣節點情況如下:
主節點 | 從節點 | 哈希槽 |
---|---|---|
192.168.78.100:6381 | 192.168.78.100:6385 | 1365-5460 |
192.168.78.100:6382 | 192.168.78.100:6386 | 6827-10922 |
192.168.78.100:6383 | 192.168.78.100:6384 | 12288-16383 |
192.168.78.100:6387 | 192.168.78.100:6388 | 0-1364 5461-6826 10923-12287 |
在擴容後的集羣環境下,再次查看之前存儲的數據,數據還能正常讀取,數據也可以存儲到6387
節點。
六、集羣的縮容
在流量降下來後,需要把之前擴容的機器下線,避免資源的浪費。
此時只需要把從機6388
從集羣中刪除,然後把6387
的槽點清空,重新分配槽點,再把6387
節點也刪除,最後把6387
和6388
節點停機,這樣就完成縮容了。
# 進入6381節點,刪除6387節點
docker exec -it redis-node-1 /bin/bash
redis-cli --cluster del-node 192.168.78.100:6388 c99eb43d05cb017ad717104051cb4e2341ead739
c99eb43d05cb017ad717104051cb4e2341ead739是6388節點的ID。
此時可看到6387
節點的從節點已經不在了。
# 重新分配槽位
redis-cli --cluster reshard 192.168.78.100:6381
再次檢查集羣情況,槽位已經被遷移到6381節點了:
redis-cli --cluster check 192.168.78.100:6381
然後在把6387
節點刪除,再次檢查集羣情況,6387
節點已經不在了:
redis-cli --cluster del-node 192.168.78.100:6387 156f002af4e395f547f0262c5db2b54e634a1fda
最後再把6387和6388兩臺機器關掉:
docker stop redis-node-7
docker stop redis-node-8
完成redis集羣的縮容。