目錄
一.?原理簡述
二. 集群配置???????
2.1 環境準備
2.2 編譯安裝一個redis
2.3 創建集群
2.4 寫入數據測試
實驗一:
實驗二:
實驗三:?
實驗四:
添加節點
自動分配槽位
提升節點為master:
實驗五:
實驗六:
實驗七:
?官網文檔(Redis集群規范) Redis cluster specification | Docs
一.?原理簡述
此處的集群指的是Cluster, 通過分區/分片來實現一定程度的分布式與高可用部署。
二. 集群配置
Redis 最小集群規劃,需要包含至少三個主節點,此處測試部署具有三個主服務器和三個從服務器的六節點群集。計劃是在一臺機器上模擬一個集群,主節點端口為三個, 從節點三個,這和生產環境的集群搭建沒本質區別。下面的配置就將創建的六個redis實例端口修改為7001,7002,7003,7004,7005,7006,每個虛擬機中部署兩個redis實例。
命令 | 含義 |
---|---|
cluster info | 獲取集群的狀態信息,包括插槽狀態、節點數量等。 |
cluster nodes | 獲取集群中所有節點的詳細信息,包括節點ID、角色、狀態等。 |
cluster meet <ip> <port> | 將新的節點加入到集群中。 |
cluster addslots <slot> | 為當前節點分配一個或多個插槽。 |
cluster delslots <slot> | 從當前節點刪除一個或多個插槽。 |
cluster setslot <slot> <node-id> | 將一個插槽分配給指定節點。 |
cluster replicate <node-id> | 將當前節點設置為目標節點的從節點。 |
cluster failover | 觸發趨向安全的故障轉移,將當前從節點提升為主節點。 |
cluster reset | 重置集群狀態(謹慎使用),可以選擇溫和模式或硬重置模式。CLUSTER RESET ?命令可以選擇溫和模式(soft reset)或硬重置模式(hard reset)。溫和模式通常只清除槽位信息而不改變節點ID,而硬重置模式則會生成新的節點ID。默認為溫和重置模式。 |
cluster saveconfig | 將當前集群配置數據保存到集群節點的配置文件中。 |
cluster replicas <node-id> | 列出指定主節點的所有從節點。 |
cluster myid | 獲取當前節點的ID。 |
cluster slots | 獲取集群中所有插槽的分布情況。 |
cluster flushslots | 清空當前節點的所有插槽信息。 |
cluster keyslot <key> | 根據給定的鍵值計算出其對應的插槽。 |
刪除節點的步驟
步驟 | 命令 | 含義 |
---|---|---|
數據遷移 | redis-cli --cluster reshard --cluster-from <源節點ID> --cluster-to <目標節點ID> --cluster-slots <遷移插槽數> -h <集群中的任一節點IP> -p <端口> ?或 手動使用cluster setslot 命令 | 將待刪除節點的數據遷移到其他節點(可以手動也可自動)。 |
節點刪除 | redis-cli -h <其他節點IP> -p <其他節點端口> cluster forget <節點ID> | 通知集群中的其他節點忘記被刪除的節點。 |
節點下線(可選) | redis-cli -h <節點IP> -p <節點端口> shutdown | 關閉被刪除節點的Redis服務器實例。 |
2.1 環境準備
localhost | rocky_linux9.4 | 192.168.226.21 | redis5.0.10 |
localhost | rocky_linux9.4 | 192.168.226.22 | redis5.0.10 |
localhost | rocky_linux9.4 | 192.168.226.23 | redis5.0.10 |
關閉防火墻和selinux,時間同步。
2.2 編譯安裝一個redis
?現在選擇第一臺192.168.226.21進行先編譯安裝一個redis,步驟如下
[root@localhost ~]# wget http://download.redis.io/releases/redis-5.0.10.tar.gz #下載redis
[root@localhost ~]# tar xzf redis-5.0.10.tar.gz -C /usr/local #解壓
[root@localhost ~]# cd /usr/local/
[root@localhost local]# mv redis-5.0.10/ redis7001
[root@localhost local]# cd redis7001/
[root@localhost redis]# yum install -y gcc make #安裝編譯工具
[root@localhost redis]# make
注:如果報錯請將剛才解壓的安裝包刪除掉,再次重新解壓并進行make安裝即可。#以下為定義參數
#創建持久化數據目錄
[root@localhost ~]# mkdir /usr/local/redis7001/data
[root@localhost ~]# cd /usr/local/redis7001
[root@localhost redis7001]# cp redis.conf redis.conf.bak #備份配置文件
[root@localhost redis7001]# vim redis.conf #在配置文件中找到修改如下bind 0.0.0.0 #默認ip為127.0.0.1 需要改為其他節點機器可訪問的ip 否則創建集群時無法訪問對應的端口,無法創建集群
pidfile /var/run/redis_7001.pid #pidfile文件對應7001,7002,7003,7004,7005,7006
dir /usr/local/redis7001/data/ #數據文件存放位置對應7001,7002,7003,7004,7005,7006
port 7001 #端口7001
timeout 300
daemonize yes #redis后臺運行
pidfile "/var/log/redis7001.log" #日志目錄
cluster-enabled yes #開啟集群
cluster-config-file nodes-7001.conf #集群配置信息,開啟集群后自動生成
cluster-node-timeout 5000 #請求超時時長
appendonly yes #開啟aof日志,它會每次寫操作都記錄一條日志
[root@localhost redis7001]# cd #拷貝五個redis實例,每個虛擬里放兩個redis實例
[root@localhost ~]# cd ~ && cp -r /usr/local/redis7001 /usr/local/redis7002[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.22:/usr/local/redis7003
[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.22:/usr/local/redis7004
[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.23:/usr/local/redis7005
[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.23:/usr/local/redis7006
#修改剩下五個實例中的7001為自己對應的號
[root@localhost ~]# vim /usr/local/redis7002/redis.conf
#在配置未見中使用語法 :%s/7001/7002/g 即可快速匹配替換,然后保存退出
#在另外兩個主機中,對剩下的四個redis實例用也同樣的方法去快速匹配修改,注意在命令中修改數字,這里不在贅述
啟動六個redis實例,并查驗端口是否正常
#對192.168.226.21操作
[root@localhost ~]# /usr/local/redis7001/src/redis-server /usr/local/redis7001/redis.conf
[root@localhost ~]# /usr/local/redis7001/src/redis-server /usr/local/redis7002/redis.conf
[root@localhost ~]# ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:17001 0.0.0.0:* users:(("redis-server",pid=7908,fd=9))
LISTEN 0 511 0.0.0.0:17002 0.0.0.0:* users:(("redis-server",pid=7914,fd=9))
LISTEN 0 511 0.0.0.0:7001 0.0.0.0:* users:(("redis-server",pid=7908,fd=6))
LISTEN 0 511 0.0.0.0:7002 0.0.0.0:* users:(("redis-server",pid=7914,fd=6))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=854,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=854,fd=4)) #對192.168.226.22操作
[root@localhost local]# /usr/local/redis7003/src/redis-server /usr/local/redis7003/redis.conf
[root@localhost local]# /usr/local/redis7003/src/redis-server /usr/local/redis7004/redis.conf
[root@localhost local]# ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:7004 0.0.0.0:* users:(("redis-server",pid=10220,fd=6))
LISTEN 0 511 0.0.0.0:7003 0.0.0.0:* users:(("redis-server",pid=10215,fd=6))
LISTEN 0 511 0.0.0.0:17004 0.0.0.0:* users:(("redis-server",pid=10220,fd=9))
LISTEN 0 511 0.0.0.0:17003 0.0.0.0:* users:(("redis-server",pid=5693,fd=6))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=859,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=859,fd=4)) #對192.168.226.23操作
[root@localhost ~]# /usr/local/redis7005/src/redis-server /usr/local/redis7005/redis.conf
[root@localhost ~]# /usr/local/redis7006/src/redis-server /usr/local/redis7006/redis.conf
[root@localhost ~]# ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:17006 0.0.0.0:* users:(("redis-server",pid=1783,fd=9))
LISTEN 0 511 0.0.0.0:17005 0.0.0.0:* users:(("redis-server",pid=1778,fd=9))
LISTEN 0 511 0.0.0.0:7006 0.0.0.0:* users:(("redis-server",pid=1783,fd=6))
LISTEN 0 511 0.0.0.0:7005 0.0.0.0:* users:(("redis-server",pid=1778,fd=6))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=858,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=858,fd=4))
#上面啟動命令中,有些前面的對應的數字沒修改成對應數字是可以的,但是后面那個必須要對號才行。
2.3 創建集群
# 注意ip和端口的對應,這里用第一個,即7001的redis實例創建,如果換機器注意修改數字,--cluster-replicas 1是指定每個主節點有一個從節點
[root@localhost ~]# /usr/local/redis7001/src/redis-cli --cluster create --cluster-replicas 1 192.168.226.21:7001 192.168.226.21:7002 192.168.226.22:7003 192.168.226.22:7004 192.168.226.23:7005 192.168.226.23:7006
啟動后接下開會有提示,對照后輸入yes即可,這里一定要輸入的是yes,不能是簡寫y,如下圖:
?創建完成后,驗證集群狀態:
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster info
cluster_state:ok #表示集群狀態是正常的
cluster_slots_assigned:16384 #表示集群中的插槽已分配的數量是16384,這是Redis集群的最大插槽數量。
cluster_slots_ok:16384 #表示集群中的插槽正常的數量是16384。
cluster_slots_pfail:0 #表示在插槽中標記為疑似故障(pfail)的節點數量是0。
cluster_slots_fail:0 #表示在插槽中標記為故障(fail)的節點數量是0。
cluster_known_nodes:6 #表示集群中已知節點的總數是6。
cluster_size:3 #表示集群的大小(即主節點的數量)是3。
cluster_current_epoch:6 #集群當前的配置版本(或配置紀元)。
cluster_my_epoch:1 #該節點最后一次選舉的配置版本。
cluster_stats_messages_ping_sent:362 #此節點發送的ping消息數量。
cluster_stats_messages_pong_sent:331 #此節點發送的pong消息數量。
cluster_stats_messages_sent:693 #此節點發送的總消息數量。
cluster_stats_messages_ping_received:326 #此節點接收的ping消息數量。
cluster_stats_messages_pong_received:362 #此節點接收的pong消息數量。
cluster_stats_messages_meet_received:5 #此節點接收的meet消息數量。
cluster_stats_messages_received:693 #此節點接收的總消息數量。ping:這是一個節點向其他節點發送的消息,用于檢查其他節點的健康狀態。當一個節點發送ping消息后,如果目標節點是活動的,它會回復一個pong消息。
pong:這是一個節點在收到其他節點的ping消息后發送的響應消息。它是對ping消息的響應,表示該節點當前是活動的。
meet:這是一種特殊類型的消息,當一個節點想要加入到集群中時會發送此消息。當一個節點收到meet消息后,它會將這個新節點添加到它所知道的節點列表中,并將這個信息通過ping消息傳播給其他節點,以此方式把新節點引入到集群網絡中。
使用以下命令查看集群中每個節點的狀態?(當前登錄的會在里面用myself標識出來,本下面第五行就標識出來了)
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster nodes
870ed4837bcfc5d8e455c04ff4e2ec39156a652b 192.168.226.21:7002@17002 slave b0dc2767920f8e319e59709a88252cd46cfdda6d 0 1719391362667 5 connected
852c2c534e007a5155f96fba95c8333e334a5c3e 192.168.226.22:7004@17004 slave e4264f2bfaff2546625b9a8f559a0e822c5e24e1 0 1719391363820 4 connected
4cad4eebb85a849614ecaffeeb4b73da032fd974 192.168.226.22:7003@17003 master - 0 1719391362773 3 connected 5461-10922
e4264f2bfaff2546625b9a8f559a0e822c5e24e1 192.168.226.21:7001@17001 myself,master - 0 1719391359000 1 connected 0-5460
171b2751e63e86aa5335c149804a0e435dbb6f7f 192.168.226.23:7006@17006 slave 4cad4eebb85a849614ecaffeeb4b73da032fd974 0 1719391364235 6 connected
b0dc2767920f8e319e59709a88252cd46cfdda6d 192.168.226.23:7005@17005 master - 0 1719391363503 5 connected 10923-16383
2.4 寫入數據測試
實驗一:
使用當前主機節點連接別的主機節點,插入數據測試,提示失敗
#不適用-c參數連接一個節點,結果不然插入數據,對應的哈希槽不匹配
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.23 -p 7006
192.168.226.23:7006> keys *
(empty list or set)
192.168.226.23:7006> set name zhangsan
(error) MOVED 5798 192.168.226.22:7003#使用-c參數連接節點后插入數據,結果可以正常插入,他會自動插入到對應的哈希槽
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -c -h 192.168.226.23 -p 7006
192.168.226.23:7006> set age grg
-> Redirected to slot [741] located at 192.168.226.21:7001
OK
192.168.226.21:7001> set name lisi
-> Redirected to slot [5798] located at 192.168.226.22:7003
OK
在 Redis 集群中,每個主節點和從節點負責特定的哈希槽范圍。哈希槽(hash slot)是 Redis 集群中的一個概念,用于將鍵分配到不同的節點。Redis 集群將鍵映射到 16384 個哈希槽,然后將這些哈希槽分配給不同的節點。使用 -c 參數(即“cluster mode”)來運行 redis-cli 是因為這個模式會處理 Redis 集群的特定行為,特別是當節點之間存在鍵的重定向時。這是因為 Redis 集群中的每個鍵都映射到特定的哈希槽,而每個哈希槽又由集群中的特定節點負責。如果你嘗試在沒有集群模式的情況下訪問不屬于該節點的鍵,Redis 將返回一個 MOVED 錯誤,指示你重定向到正確的節點。當你使用 redis-cli 連接到 Redis 集群并進行操作時,集群模式會自動處理這些重定向。這意味著,如果你試圖訪問一個不在當前節點處理范圍內的鍵,redis-cli 將自動重定向你的請求到正確的節點。
實驗二:
隨機連接一個節點,這次使用-c參數連接后插入多條數據
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -c -h 192.168.226.23 -p 7006
192.168.226.23:7006> set age grg
-> Redirected to slot [741] located at 192.168.226.21:7001
OK
192.168.226.21:7001> set name lisi
-> Redirected to slot [5798] located at 192.168.226.22:7003
OK
192.168.226.22:7003>
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -c -h 192.168.226.22 -p 7004
192.168.226.22:7004> keys *
1) "age"
192.168.226.22:7004> set a b
-> Redirected to slot [15495] located at 192.168.226.23:7005
OK
192.168.226.23:7005> set e g
OK
192.168.226.23:7005> set q a
OK
192.168.226.23:7005> set age 99
-> Redirected to slot [741] located at 192.168.226.21:7001
OK
192.168.226.21:7001> keys *
1) "age"
192.168.226.21:7001> set dgd sdf
-> Redirected to slot [14644] located at 192.168.226.23:7005
OK
192.168.226.23:7005> set 1 2
-> Redirected to slot [9842] located at 192.168.226.22:7003
OK
192.168.226.22:7003> keys *
1) "name"
2) "1"
192.168.226.22:7003> get age
-> Redirected to slot [741] located at 192.168.226.21:7001
"99"
192.168.226.21:7001> get e
-> Redirected to slot [15363] located at 192.168.226.23:7005
"g"
通過多次插入數據和查看發現,在插入時會被重定向,數據會被重定向到對應的哈希槽,同時所處的節點也會隨之移動,并且查看所有key時,只能看到當前節點機器的key,隨便看不到別的節點的key,但是使用get去查看別的節點存在的key,也是可以看到其對應的值的,只是在自己所處的節點不能看到別的節點的key。
簡述總結:
當使用 -c
參數連接 Redis 集群時,會觀察到以下行為和特點:
-
自動鍵重定向:
- 當執行命令時,
redis-cli
會根據鍵的哈希槽信息自動將命令發送到負責該鍵的節點上執行。 - 如果鍵的哈希槽不在當前連接的節點上,
redis-cli
會自動重定向命令到正確的節點執行,執行成功后返回結果。
- 當執行命令時,
-
節點的鍵查看限制:
- 每次連接到一個節點后,只能查看該節點負責的鍵,而不能查看整個集群的所有鍵。
- 這意味著在一個節點上執行
keys *
命令只會返回該節點負責的鍵列表,而不是整個集群的所有鍵。
-
位置變動:
- 如果集群的主從節點發生變化或者數據遷移,同一個鍵可能會被分配到不同的節點上。
- 因此,多次連接并查看鍵的位置可能會發現鍵在不同節點上的分布情況有所改變。
-
集群管理和數據一致性:
- Redis 集群通過哈希槽來管理數據分片和負載均衡,自動將數據分散到不同的節點上。
- 當節點加入或離開集群時,集群會重新分配哈希槽,保證數據的高可用性和一致性。
實驗三:?
現在實驗掛掉一個節點和掛掉一對主從節點測試。
從前面看到的分配的主從配對信息中,選擇從節點192.168.226.21:7002和主節點192.168.226.23:7005來測試
首先將192.168.226.23:7005關閉服務,看從節點變化。
對192.168.226.23主機操作:
[root@localhost local]# /usr/local/redis7005/src/redis-cli -h 192.168.226.23 -p 7005 shutdown
[root@localhost ~]# ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:17006 0.0.0.0:* users:(("redis-server",pid=1783,fd=9))
LISTEN 0 511 0.0.0.0:7006 0.0.0.0:* users:(("redis-server",pid=1783,fd=6))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=858,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=858,fd=4)) #查看集群中每個節點的狀態?
[root@localhost ~]# /usr/local/redis7006/src/redis-cli -h 192.168.226.23 -p 7006 cluster nodes
4cad4eebb85a849614ecaffeeb4b73da032fd974 192.168.226.22:7003@17003 master - 0 1719492508192 3 connected 5461-10922
e4264f2bfaff2546625b9a8f559a0e822c5e24e1 192.168.226.21:7001@17001 master - 0 1719492507000 1 connected 0-5460
870ed4837bcfc5d8e455c04ff4e2ec39156a652b 192.168.226.21:7002@17002 master - 0 1719492507187 7 connected 10923-16383
171b2751e63e86aa5335c149804a0e435dbb6f7f 192.168.226.23:7006@17006 myself,slave 4cad4eebb85a849614ecaffeeb4b73da032fd974 0 1719492508000 6 connected
852c2c534e007a5155f96fba95c8333e334a5c3e 192.168.226.22:7004@17004 slave e4264f2bfaff2546625b9a8f559a0e822c5e24e1 0 1719492506179 4 connected
b0dc2767920f8e319e59709a88252cd46cfdda6d 192.168.226.23:7005@17005 master,fail - 1719492406717 1719492406616 5 disconnected
可以發現把一個主節點關閉后,在集群信息中會被標記故障,然后對應的從節點會變成主機點
現在把192.168.226.23:7005的redis服務啟動再觀察:
#啟動192.168.226.23:7005的redis服務
[root@localhost local]# /usr/local/redis7005/src/redis-server /usr/local/redis7005/redis.conf
[root@localhost local]# ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:17006 0.0.0.0:* users:(("redis-server",pid=1783,fd=9))
LISTEN 0 511 0.0.0.0:17005 0.0.0.0:* users:(("redis-server",pid=1836,fd=9))
LISTEN 0 511 0.0.0.0:7006 0.0.0.0:* users:(("redis-server",pid=1783,fd=6))
LISTEN 0 511 0.0.0.0:7005 0.0.0.0:* users:(("redis-server",pid=1836,fd=6))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=858,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=858,fd=4))
[root@localhost ~]# /usr/local/redis7006/src/redis-cli -h 192.168.226.22 -p 7003 -c
192.168.226.22:7003> cluster nodes
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 master - 0 1719499652547 1 connected 0-5460
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719499653000 7 connected
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 myself,master - 0 1719499653000 3 connected 5461-10922
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 slave 978977953ce8a5ee9a3363863f24b4ce902fc216 0 1719499653047 4 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave c1250f1610d7328dba13a030f89257b480c0d781 0 1719499653852 6 connected
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719499652547 7 connected 10923-16383
192.168.226.22:7003>
可以看到192.168.226.23:7005的redis再開啟服務后就變成了從節點,原來一組的從節點192.168.226.21:7002變成了主節點。
現在將這一對主從節點都停止服務測試:
#對192.168.226.23主機操作
[root@localhost ~]# /usr/local/redis7005/src/redis-cli -h 192.168.226.23 -p 7005 shutdown
#對192.168.226.21主機操作
[root@localhost ~]# /usr/local/redis7002/src/redis-cli -h 192.168.226.21 -p 7002 shutdown#使用192.168.226.21主機連接redis
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 -c
192.168.226.21:7001> cluster nodes
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 slave 978977953ce8a5ee9a3363863f24b4ce902fc216 0 1719403248009 4 connected
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 myself,master - 0 1719403227000 1 connected 0-5460
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave,fail 3473b893f94e01fee0f7be54cb53007440e487ea 1719403235885 1719403234851 7 disconnected
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master,fail - 1719403230400 1719403229172 7 disconnected 10923-16383
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 master - 0 1719403247374 3 connected 5461-10922
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave c1250f1610d7328dba13a030f89257b480c0d781 0 1719403247798 6 connected
192.168.226.21:7001> keys *
1) "www"
2) "age"
192.168.226.21:7001> get www
(error) CLUSTERDOWN The cluster is down
192.168.226.21:7001> set big 8888
(error) CLUSTERDOWN The cluster is down
192.168.226.21:7001>
?可以看到不能看數據,也不能寫數據。CLUSTERDOWN The cluster is down
錯誤表明 Redis 集群當前處于非活動狀態,可能是因為集群中的某些節點無法正常通信或集群配置出現了問題。因此,當一對互為主從的節點宕機,則集群不可用。
現在將原來先將192.168.226.23:7005開啟服務
[root@localhost local]# /usr/local/redis7005/src/redis-server /usr/local/redis7005/redis.conf
將驗證,即便先起來也不代表會先成為master節點。
現在再將192.168.226.21:7002恢復redis服務
[root@localhost ~]# /usr/local/redis7002/src/redis-server /usr/local/redis7002/redis.conf
實驗四:
添加節點
此時我們新增一個虛擬機,拷貝兩個redis實例并啟動
localhost | rocky_linux9.4 | 192.168.226.24 | redis5.0.10 |
確認關閉防火墻和selinux,進行時間同步。
從192.168.226.21主機中拷貝兩個redis實例到192.168.226.24主機中。
#對192.168.226.21操作進行拷貝
[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.24:/usr/local/redis7007
[root@localhost ~]# scp -r /usr/local/redis7001 root@192.168.226.24:/usr/local/redis7008
#對192.168.226.24主機修改配置文件
[root@localhost ~]# vim /usr/local/redis7007/redis.conf#使用:%s/7001/7007/g 然后保存退出[root@localhost ~]# vim /usr/local/redis7008/redis.conf#使用:%s/7001/7008/g 然后保存退出#啟動兩個redis實例
[root@localhost ~]# /usr/local/redis7007/src/redis-server /usr/local/redis7007/redis.conf[root@localhost ~]# /usr/local/redis7007/src/redis-server /usr/local/redis7008/redis.conf#驗證啟動
[root@localhost ~]# ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:7008 0.0.0.0:* users:(("redis-server",pid=1416,fd=6))
LISTEN 0 511 0.0.0.0:7007 0.0.0.0:* users:(("redis-server",pid=1411,fd=6))
LISTEN 0 511 0.0.0.0:17007 0.0.0.0:* users:(("redis-server",pid=1411,fd=9))
LISTEN 0 511 0.0.0.0:17008 0.0.0.0:* users:(("redis-server",pid=1416,fd=9))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=849,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=849,fd=4))
要添加節點,首先啟動redis實例,用集群中的主機連接任一實例去添加這個新節點。
選擇192.168.226.21去操作添加:
#添加主節點
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7002 cluster meet 192.168.226.24 7007#查看集群中每個節點的狀態
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.24 -p 7002 cluster nodes
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719502625187 7 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 slave 978977953ce8a5ee9a3363863f24b4ce902fc216 0 1719502623179 1 connected
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719502623000 7 connected 10923-16383
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 master - 0 1719502623681 3 connected 5461-10922
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 myself,slave 978977953ce8a5ee9a3363863f24b4ce902fc216 0 1719502622000 0 connected
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 master - 0 1719502624183 1 connected 0-5460
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave c1250f1610d7328dba13a030f89257b480c0d781 0 1719502624000 3 connected
驗證集群狀態
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7002 cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:7
cluster_size:3
cluster_current_epoch:7
cluster_my_epoch:7
cluster_stats_messages_ping_sent:3969
cluster_stats_messages_pong_sent:3466
cluster_stats_messages_meet_sent:1
cluster_stats_messages_update_sent:2
cluster_stats_messages_sent:7438
cluster_stats_messages_ping_received:3466
cluster_stats_messages_pong_received:3970
cluster_stats_messages_received:7436
#再添加一個節點
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster meet 192.168.226.24 7008#給新增的節點設置其對應的主節點,后面的字符串就是主節點的ID,通過前面用cluster nodes獲取到的
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.24 -p 7008 cluster replicate c1250f1610d7328dba13a030f89257b480c0d781
這兩個命令用法:
/path路徑/redis/src/redis-cli -h <已有節點IP> -p <已有節點端口> cluster meet <新節點IP> <新節點端口> /path路徑/redis/src/redis-cli -h <新節點IP> -p <新節點端口> cluster replicate <已有節點ID>
注:
添加節點有一種情況是添加進去就是master,有一種情況添加后就是slave?,如果是slave那么執行使用cluster reset 重置這個節點再次重新添加至集群內嘗試。
/usr/local/redis7001/src/redis-cli -h 192.168.226.24 -p 7007 cluster reset
自動分配槽位
[root@localhost ~]# /usr/local/redis7001/src/redis-cli --cluster rebalance 192.168.226.24:7007
>>> Performing Cluster Check (using node 192.168.226.24:7007)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
*** No rebalancing needed! All nodes are within the 2.00% threshold.[root@localhost ~]# /usr/local/redis7001/src/redis-cli --cluster rebalance 192.168.226.24:7008
>>> Performing Cluster Check (using node 192.168.226.24:7008)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
*** No rebalancing needed! All nodes are within the 2.00% threshold.
提升節點為master:
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.24 -p 7007 cluster failover
假設我給192.168.226.24:7007 把其從節點提升為主節點,使用CLUSTER FAILOVER命令后,會讓原有的注意點之一降級為從節點,其原理解釋如下:
在Redis集群中,執行CLUSTER FAILOVER
命令后,所有的從節點都會嘗試進行故障轉移,結果是你指定的節點變為了主節點。執行過程中的變化可以解釋為什么會發生角色改變。
執行的步驟
-
初始狀態:
192.168.226.24:7007
為從節點。192.168.226.21:7001
、192.168.226.21:7002
、192.168.226.22:7003
是主節點。
-
執行故障轉移:
- 當你在
192.168.226.24:7007
(原從節點)執行CLUSTER FAILOVER
命令時,這個從節點被提升為主節點。
- 當你在
故障轉移過程
故障轉移過程中:
- 原主節點(
192.168.226.21:7001
)的角色變為了從節點,以保持數據的高可用性和一致性。 - 具體來說,執行
CLUSTER FAILOVER
命令后,192.168.226.24:7007
從節點被提升為主節點,原主節點(192.168.226.21:7001
)被降級為從節點。這就是為什么看到的新輸出中192.168.226.24:7007
變為了主節點,而192.168.226.21:7001
變為了從節點。
新的集群狀態解釋
新的狀態如下:
-
主節點:
192.168.226.24:7007
192.168.226.21:7002
192.168.226.22:7003
-
從節點:
192.168.226.21:7001
(從原主節點降級)192.168.226.23:7005
192.168.226.22:7004
192.168.226.24:7008
192.168.226.23:7006
新狀態變更后,新的主節點和從節點的對應關系保持如下:
- 新主節點
192.168.226.24:7007
接管了原主節點192.168.226.21:7001
的插槽范圍0-5460
。
變化主要是為了保持群集的高可用性和數據的一致性,同時你也成功完成了將從節點提升為主節點的操作。
#驗證重新平衡
[root@localhost ~]# /usr/local/redis7001/src/redis-cli --cluster check 192.168.226.24:7008
192.168.226.24:7008 (7a98972a...) -> 1 keys | 5462 slots | 2 slaves.
192.168.226.23:7005 (2544360a...) -> 3 keys | 5461 slots | 1 slaves.
192.168.226.24:7007 (94d037d0...) -> 2 keys | 5461 slots | 2 slaves.
[OK] 6 keys in 3 masters.
0.00 keys per slot on average.
>>> Performing Cluster Check (using node 192.168.226.24:7008)
M: 7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008slots:[5461-10922] (5462 slots) master2 additional replica(s)
S: 3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002slots: (0 slots) slavereplicates 2544360a6e3ea711151312abb829037fe1b72163
S: 51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006slots: (0 slots) slavereplicates 7a98972ab9a038538c2106d1e6c52915d5e3999d
M: 2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005slots:[10923-16383] (5461 slots) master1 additional replica(s)
S: faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004slots: (0 slots) slavereplicates 94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4
S: 978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001slots: (0 slots) slavereplicates 94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4
S: c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003slots: (0 slots) slavereplicates 7a98972ab9a038538c2106d1e6c52915d5e3999d
M: 94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007slots:[0-5460] (5461 slots) master2 additional replica(s)
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
實驗五:
使用gorget忘記一個redis實例。
在這之前的實驗添加了兩個節點,并將192.168.226.24:7007的實例提升為master節點,并導致整個集群從節點都會嘗試進行故障轉移,新的主從信息如下查看:
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster nodes
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 master - 0 1719457085420 8 connected 0-5460
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 myself,slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719457085000 1 connected
7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008@17008 master - 0 1719457086078 9 connected 5461-10922
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719457086196 11 connected 10923-16383
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719457086000 9 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 slave 94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 0 1719457086519 8 connected
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719457087281 11 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719457087756 9 connected
現在進行忘記一個從節點(后面的字符串是指定節點對應的ID,可在上面查看到的信息找到每個節點對應ID):
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster forget 2544360a6e3ea711151312abb829037fe1b72163
?再查詢每個節點的狀態
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster nodes
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 master - 0 1719457172640 8 connected 0-5460
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 myself,slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719457171000 1 connected
7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008@17008 master - 0 1719457173425 9 connected 5461-10922
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719457172745 11 connected 10923-16383
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719457173085 9 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 slave 94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 0 1719457172000 8 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719457172306 9 connected[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.22 -p 7004 cluster nodes
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 slave faa30f7980bda533b25558ad6656dee6f3a40566 0 1719551425478 12 connected
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719551425000 11 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719551425804 9 connected
7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008@17008 master - 0 1719551426555 9 connected 5461-10922
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719551425000 9 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 myself,master - 0 1719551424000 12 connected 0-5460
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719551426000 11 connected 10923-16383
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719551425000 11 connected
使用forget只是在當前節點忘記了指定ID的節點信息,但是其他節點還是存在這個信息。
使用?CLUSTER FORGET
?命令來忘記一個 Redis 集群節點時,這個命令實際上是從當前節點的集群配置中移除了指定的節點信息。但是,這并不意味著該節點從整個集群中完全消失了。
集群中的其他節點可能仍然知道這個被忘記的節點,并且?cluster_known_nodes
?的計數可能會繼續包含它,直到這些節點也執行了?CLUSTER FORGET
?命令或者通過集群的自動重新配置過程(如故障轉移或重新平衡)來更新它們的集群配置。
如果在 Redis 集群中的所有其他節點上都使用?CLUSTER FORGET
?命令忘記了7005節點的集群ID,那么從集群管理的角度來看,7005節點就已經從集群配置中被移除了。然而,僅僅這樣做并不意味著7005節點已經停止運行或已從物理上刪除。如果還需要確保7005節點不再運行并且釋放其占用的資源,可以則停止7005節點的服務,刪除7005節點的數據和配置文件等方法。
請注意,如果7005節點在?CLUSTER FORGET
?操作之后重新啟動,并且它仍然保留有之前的集群狀態信息(特別是?nodes.conf
?文件),它可能會嘗試重新加入集群。因此,徹底刪除7005節點的數據和配置文件是確保它不再參與集群的關鍵步驟。
執行forget后,重啟7005節點后,在使用forget那個節點那又可以查看到7005節點的信息了
實驗六:
在實驗五中僅僅使用forgrt命令測試忘記節點,那么在重新啟動被forget的redis節點,就又可以恢復了。
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster nodes
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 slave faa30f7980bda533b25558ad6656dee6f3a40566 0 1719459359290 12 connected
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 myself,slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719459355000 1 connected
7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008@17008 master - 0 1719459360597 9 connected 5461-10922
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719459360171 11 connected 10923-16383
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719459359513 9 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 master - 0 1719459360054 12 connected 0-5460
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 3473b893f94e01fee0f7be54cb53007440e487ea 0 1719459360597 11 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719459358413 9 connected
接下來嘗試節點縮容。
被縮容節點和接收數據槽的幾點都要求為主節點才可,在Redis集群中,只有主節點才能擁有哈希槽(slots)。
根據上述集群信息和對應ID,以及下述語法
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 --cluster reshard 192.168.226.21:7002 --cluster-from 3473b893f94e01fee0f7be54cb53007440e487ea --cluster-to 7a98972ab9a038538c2106d1e6c52915d5e3999d --cluster-slots 5461 --cluster-yes# --cluster-from 要縮容的主節點id
# --cluster-to 縮容之后的數據槽點分給哪一個master
# --cluster-slots 要縮容的主節點id的槽位數量
# --cluster-yes 可以自動執行而無需手動確認(可加可不加)
再次查詢信息
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 cluster nodes
94d037d03b44f77db95acbcf6b8fa9ffa5cb95b4 192.168.226.24:7007@17007 slave faa30f7980bda533b25558ad6656dee6f3a40566 0 1719460937784 12 connected
978977953ce8a5ee9a3363863f24b4ce902fc216 192.168.226.21:7001@17001 myself,slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719460936000 1 connected
7a98972ab9a038538c2106d1e6c52915d5e3999d 192.168.226.24:7008@17008 master - 0 1719460936000 13 connected 5461-16383
3473b893f94e01fee0f7be54cb53007440e487ea 192.168.226.21:7002@17002 master - 0 1719460937324 11 connected
c1250f1610d7328dba13a030f89257b480c0d781 192.168.226.22:7003@17003 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 1719460938127 1719460935871 13 connected
faa30f7980bda533b25558ad6656dee6f3a40566 192.168.226.22:7004@17004 master - 0 1719460937903 12 connected 0-5460
2544360a6e3ea711151312abb829037fe1b72163 192.168.226.23:7005@17005 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719460937022 13 connected
51db12ce426015bbabda015e2bb3564f0858b43e 192.168.226.23:7006@17006 slave 7a98972ab9a038538c2106d1e6c52915d5e3999d 0 1719460936206 13 connected
實驗七:
刪除一個從節點
(推薦先刪除從節點,后刪除主幾點)
下面是刪除的命令,后面要跟的是被刪除節點IP和端口,然后就是ID
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 --cluster del-node 192.168.226.23:7006 51db12ce426015bbabda015e2bb3564f0858b43e
可以看到沒有7006的節點了。
刪除主節點?
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 --cluster del-node 192.168.226.21:7002 3473b893f94e01fee0f7be54cb53007440e487ea
?
錯誤原因:
[root@localhost ~]# /usr/local/redis7001/src/redis-cli -h 192.168.226.21 -p 7001 --cluster del-node 192.168.226.24:7008 7a98972ab9a038538c2106d1e6c52915d5e3999d
>>> Removing node 7a98972ab9a038538c2106d1e6c52915d5e3999d from cluster 192.168.226.24:7008
[ERR] Node 192.168.226.24:7008 is not empty! Reshard data away and try again.
?錯誤信息提示正在嘗試從集群中刪除一個非空的節點(7a98972ab9a038538c2106d1e6c52915d5e3999d
),但是該節點上仍然有哈希槽(slots)和數據。在Redis集群中,不能直接刪除一個包含數據的節點,因為這樣會丟失數據,只有當節點是空的(即它不擁有任何哈希槽和數據)時,才能使用redis-cli --cluster del-node
命令來刪除該節點。
實驗八:
刪除集群
Redis集群創建好后,一般會有以下文件生成:$ tree
.
├── appendonly.aof
├── dump.rdb
├── nodes-7000.conf
├── redis.conf
└── redis-server0 directories, 5 files其中,nodes-*.conf記錄了Redis集群的信息。要想刪除一個集群,首先關閉Redis服務,方法如下:redis-cli -h 127.0.0.1 -p 7000 shutdown關閉所有集群上節點后,進入各個節點文件夾,刪除以下文件:appendonly.aof
dump.rdb
nodes-7000.conf
批量刪除指令如下:rm -f ./*/nodes-*.conf ./*/appendonly.aof ./*/dump.rdbok,至此,舊集群已經不復存在,只留下了redis服務進程和配置文件。