Redis 超詳細自動管理Cluster集群工具上手 redis-trib.rb (多圖,手把手)


安裝介紹

​ redis-trib.rb是一款由Redis官方提供的集群管理工具,能夠大量減少集群搭建的時間。

​ 除此之外,還能夠簡化集群的檢查、槽遷徙、負載均衡等常見的運維操作,但是使用前必須要安裝ruby環境。

​ 1)使用yum進行安裝ruby:

yum install -y rubygems

​ 2)默認的ruby包管理工具鏡像源在國外,將國外源刪除添加國內源

gem sources --remove https://rubygems.org/
gem sources -a http://mirrors.aliyun.com/rubygems/
gem update --system

​ 3)使用ruby的包管理工具下載必備依賴包,由於我使用的是6.2.1的Redis,可能沒有最新的,就下載一個老版本的Redis驅動,經測試沒有任何問題:

gem install redis -v 3.3.5

​ 另外,在新版Redis中,redis-trib.rb工具的功能都被集成在了redis-cli里,但依然需要ruby環境

搭建前戲

地址規划

​ 首先我們准備2主2從的3台多實例服務器,利用redis-trib.rb工具搭建1個6節點3分片的集群(集群最少6節點)。

​ 然后再使用redis-trib.rb工具增加1台多實例服務器,組成8節點4分片的集群。

​ 之后再使用redis-trib.rb工具下線1台多實例服務器,變為6節點3分片的集群。

​ 地址規划與架構圖如下:

image-20210402153934049

在每個節點hosts文件中加入以下內容;

$ vim /etc/hosts

192.168.0.120 node1
192.168.0.130 node2
192.168.0.140 node3
192.168.0.150 node4

​ !由於該工具具有難以發現的小bug,必定出現以下問題:

  • 主從關系自動構建不准確,需要手動重新搭建主從關系,如果主從構建不合理,一旦發生災難情況后果不堪設想

集群准備

為所有節點下載Redis:

$ cd ~
$ wget https://download.redis.io/releases/redis-6.2.1.tar.gz

為所有節點配置目錄:

$ mkdir -p /usr/local/redis_cluster/redis_63{79,80}/{conf,pid,logs}

所有節點進行解壓:

$ tar -zxvf redis-6.2.1.tar.gz -C /usr/local/redis_cluster/

所有節點進行編譯安裝Redis:

$ cd /usr/local/redis_cluster/redis-6.2.1/
$ make && make install 

書寫集群配置文件,注意!Redis普通服務會有2套配置文件,一套為普通服務配置文件,一套為集群服務配置文件,我們這里是做的集群,所以書寫的集群配置文件,共6份:

$ vim /usr/local/redis_cluster/redis_6379/conf/redis.cnf

# 快速修改::%s/6379/6380/g

# 守護進行模式啟動
daemonize yes

# 設置數據庫數量,默認數據庫為0
databases 16

# 綁定地址,需要修改
bind 192.168.0.120

# 綁定端口,需要修改
port 6379

# pid文件存儲位置,文件名需要修改
pidfile /usr/local/redis_cluster/redis_6379/pid/redis_6379.pid

# log文件存儲位置,文件名需要修改
logfile /usr/local/redis_cluster/redis_6379/logs/redis_6379.log

# RDB快照備份文件名,文件名需要修改
dbfilename redis_6379.rdb

# 本地數據庫存儲目錄,需要修改
dir /usr/local/redis_cluster/redis_6379

# 集群相關配置
# 是否以集群模式啟動
cluster-enabled yes

# 集群節點回應最長時間,超過該時間被認為下線
cluster-node-timeout 15000

# 生成的集群節點配置文件名,文件名需要修改
cluster-config-file nodes_6379.conf

集群搭建

啟動集群

​ 每個節點上執行以下2條命令進行服務啟動:

$ redis-server /usr/local/redis_cluster/redis_6379/conf/redis.cnf
$ redis-server /usr/local/redis_cluster/redis_6380/conf/redis.cnf

​ 集群模式啟動,它的進程后會加上[cluster]的字樣:

$ ps -ef | grep redis
root      78586      1  0 21:56 ?        00:00:00 redis-server 192.168.0.120:6379 [cluster]
root      78616      1  0 21:56 ?        00:00:00 redis-server 192.168.0.120:6380 [cluster]
root      78636  71501  0 21:56 pts/1    00:00:00 grep --color=auto redis

​ 同時,查看一下集群節點配置文件,會發現生成了一組集群信息,每個Redis服務都是不同的:

$ cat /usr/local/redis_cluster/redis_6379/nodes_6379.conf
c71b52f728ab58fedb6e05a525ce00b453fd2f6b :0@0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0

$ cat /usr/local/redis_cluster/redis_6380/nodes_6380.conf
d645d06708e1eddb126a6c3c4e38810c188d0906 :0@0 myself,master - 0 0 0 connected
vars currentEpoch 0 lastVoteEpoch 0

# 第一段信息是這個Redis服務作為集群節點的一個身份編碼
# 別名為集群的node-id

自動化

​ 現在我們有2個部分還沒有做,1是對集群進行分槽工作,2是構建主從關系。

​ 通過redis-trib.rb工具,這個步驟將變得異常簡單,由於我的ruby是裝在node1上,所以只需要在node1執行下面一句話即可。

$ cd /usr/local/redis_cluster/redis-6.2.1/src/  

# 舊版Redis這里以腳本名開頭 redis-trib.rb 跟上后面參數即可
$ redis-cli --cluster create 192.168.0.120:6379 192.168.0.140:6380 192.168.0.130:6379 192.168.0.120:6380 192.168.0.140:6379 192.168.0.130:6380 --cluster-replicas 1

​ 參數釋義:

  • --cluster-replicas:指定的副本數,其實這一條命令的語法規則是如果副本數為1,第一個ip:port與它后面的1個ip:port建立1主1從關系,如果副本數是2,第一個ip:port與它后面的2個ip:port建立1主2從關系,以此類推

​ 執行完這條命令后,輸入yes,會看到以下信息:

$ redis-cli --cluster create 192.168.0.120:6379 192.168.0.140:6380 192.168.0.130:6379 192.168.0.120:6380 192.168.0.140:6379 192.168.0.130:6380 --cluster-replicas 1

# 主從相關
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 192.168.0.140:6379 to 192.168.0.120:6379
Adding replica 192.168.0.130:6380 to 192.168.0.140:6380
Adding replica 192.168.0.120:6380 to 192.168.0.130:6379
M: c71b52f728ab58fedb6e05a525ce00b453fd2f6b 192.168.0.120:6379
   slots:[0-5460] (5461 slots) master
M: 6a627cedaa4576b1580806ae0094be59c32fa391 192.168.0.140:6380
   slots:[5461-10922] (5462 slots) master
M: 282358c2fb0c7c16ec60f2c4043b52a0eb91e19f 192.168.0.130:6379
   slots:[10923-16383] (5461 slots) master
S: d645d06708e1eddb126a6c3c4e38810c188d0906 192.168.0.120:6380
   replicates 282358c2fb0c7c16ec60f2c4043b52a0eb91e19f
S: 7a7392cb66bea30da401d2cb9768a42bbdefc5db 192.168.0.140:6379
   replicates c71b52f728ab58fedb6e05a525ce00b453fd2f6b
S: ff53e43f9404981a51d4e744de38004a5c22b090 192.168.0.130:6380
   replicates 6a627cedaa4576b1580806ae0094be59c32fa391
   
# 詢問是否保存配置?輸入yes
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
.

# 分槽相關,全部自動進行,無需手動操作
>>> Performing Cluster Check (using node 192.168.0.120:6379)
M: c71b52f728ab58fedb6e05a525ce00b453fd2f6b 192.168.0.120:6379
   slots:[0-5460] (5461 slots) master
   1 additional replica(s)
M: 282358c2fb0c7c16ec60f2c4043b52a0eb91e19f 192.168.0.130:6379
   slots:[10923-16383] (5461 slots) master
   1 additional replica(s)
M: 6a627cedaa4576b1580806ae0094be59c32fa391 192.168.0.140:6380
   slots:[5461-10922] (5462 slots) master
   1 additional replica(s)
   
S: d645d06708e1eddb126a6c3c4e38810c188d0906 192.168.0.120:6380
   slots: (0 slots) slave
   replicates 282358c2fb0c7c16ec60f2c4043b52a0eb91e19f
S: 7a7392cb66bea30da401d2cb9768a42bbdefc5db 192.168.0.140:6379
   slots: (0 slots) slave
   replicates c71b52f728ab58fedb6e05a525ce00b453fd2f6b
S: ff53e43f9404981a51d4e744de38004a5c22b090 192.168.0.130:6380
   slots: (0 slots) slave
   replicates 6a627cedaa4576b1580806ae0094be59c32fa391
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
$

​ 仔細觀察上面的主從關系就可以看到異常,我的規划是所有的6379為主節點,而6380為從節點,顯然他沒有按照我的意思進行划分主從。

​ 這種情況還算好的,至少不同節點都是岔開的,怕就怕一台機器2個實例組成1主1從,如果是那樣的結構主從就沒有任何意義。

image-20210402113618358

主從校正

​ 由於上面自動部署時主從關系出現了問題,超乎了我們的預期(這可能是該工具的bug),所以我們要對其進行手動校正。

​ 1)登錄node3:6380,讓其作為node1:6379的從庫,由於node3:6380是一個主庫,要想變為從庫必須先清空它的插槽,而后進行指定:

$ redis-cli -h node3 -p 6380 -c
node3:6380> CLUSTER FLUSHSLOTS
node3:6380> CLUSTER REPLICATE c71b52f728ab58fedb6e05a525ce00b453fd2f6b

image-20210402112159652

​ 2)登錄node3:6379,讓該庫進行下線,此舉是為了重新上線令其角色變為master:

$ redis-cli -h node3 -p 6379 -c
node3:6379> CLUSTER RESET

image-20210402155206565

​ 3)登錄node1:6379(其實任意集群中的一個都行)重新發現node3:6379,並且記錄下缺失的插槽信息:

$ redis-cli -h node1 -p 6379 -c

node1:6379> CLUSTER MEET 192.168.0.140 6379
node1:6379> CLUSTER NODES

# 僅關注master最后這一部分信息,槽位
connected 10923-16383
connected 0-5460

# 已分配10923-16383、0-5460,缺失的插槽位為5461-10922

image-20210402155330248

​ 4)為node3:6379分配插槽:

$ redis-cli -h node3 -p 6379 cluster addslots {5461..10922}	

image-20210402155400594

​ 5)登錄node2:6380,讓其對應node3:6379,即前者作為后者的從庫

$ redis-cli -h node2 -p 6380
node2:6380> CLUSTER REPLICATE 7a7392cb66bea30da401d2cb9768a42bbdefc5db

image-20210402155436436

​ 6)查看集群是否是成功運行的狀態:

node2:6380> CLUSTER INFO
cluster_state: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:12
cluster_my_epoch:12
cluster_stats_messages_ping_sent:4406
cluster_stats_messages_pong_sent:4225
cluster_stats_messages_meet_sent:1
cluster_stats_messages_sent:8632
cluster_stats_messages_ping_received:4225
cluster_stats_messages_pong_received:4413
cluster_stats_messages_auth-req_received:4
cluster_stats_messages_received:8642

​ 7)檢查各個節點關系之間是否正常:

node2:6380> CLUSTER NODES
d645d06708e1eddb126a6c3c4e38810c188d0906 192.168.0.120:6380@16380 slave 282358c2fb0c7c16ec60f2c4043b52a0eb91e19f 0 1617335179000 3 connected
282358c2fb0c7c16ec60f2c4043b52a0eb91e19f 192.168.0.130:6379@16379 master - 0 1617335177627 3 connected 10923-16383
ff53e43f9404981a51d4e744de38004a5c22b090 192.168.0.130:6380@16380 myself,slave 7a7392cb66bea30da401d2cb9768a42bbdefc5db 0 1617335178000 12 connected
7a7392cb66bea30da401d2cb9768a42bbdefc5db 192.168.0.140:6379@16379 master - 0 1617335180649 12 connected 5461-10922
c71b52f728ab58fedb6e05a525ce00b453fd2f6b 192.168.0.120:6379@16379 master - 0 1617335179000 12 connected 0-5460
6a627cedaa4576b1580806ae0094be59c32fa391 192.168.0.140:6380@16380 slave 7a7392cb66bea30da401d2cb9768a42bbdefc5db 0 1617335179644 12 connected

​ 下面可能是我上面操作時輸錯了node-id導致的,一般按正確步驟來說不用產生這種情況。

​ *8)發現節點關系還是不正常,node3:6380也對應了node3:6379,更改一下就好了,讓其對應node1的6379:

$ redis-cli -h node3 -p 6380

node3:6380> CLUSTER REPLICATE c71b52f728ab58fedb6e05a525ce00b453fd2f6b

​ *9)再次檢查,節點關系正常:

node3:6380> CLUSTER NODES

c71b52f728ab58fedb6e05a525ce00b453fd2f6b 192.168.0.120:6379@16379 master - 0 1617335489929 12 connected 0-5460
6a627cedaa4576b1580806ae0094be59c32fa391 192.168.0.140:6380@16380 myself,slave c71b52f728ab58fedb6e05a525ce00b453fd2f6b 0 1617335490000 12 connected
282358c2fb0c7c16ec60f2c4043b52a0eb91e19f 192.168.0.130:6379@16379 master - 0 1617335487913 3 connected 10923-16383
d645d06708e1eddb126a6c3c4e38810c188d0906 192.168.0.120:6380@16380 slave 282358c2fb0c7c16ec60f2c4043b52a0eb91e19f 0 1617335488000 3 connected
7a7392cb66bea30da401d2cb9768a42bbdefc5db 192.168.0.140:6379@16379 master - 0 1617335489000 12 connected 5461-10922
ff53e43f9404981a51d4e744de38004a5c22b090 192.168.0.130:6380@16380 slave 7a7392cb66bea30da401d2cb9768a42bbdefc5db 0 1617335490931 12 connected
node3:6380>

集群擴容

發現節點

​ 現在我們的node4還沒有添加進集群,所以將node4進行添加:

$ redis-cli -h node1 -p 6379 CLUSTER MEET 192.168.0.150 6379
$ redis-cli -h node1 -p 6379 CLUSTER MEET 192.168.0.150 6380

​ 查看節點信息,對內容進行部分截取:

$ redis-cli -h node1 -p 6379  

node3:6380> cluster nodes

# 這里
f3dec547054791b01cfa9431a4c7a94e62f81db3 192.168.0.150:6380@16380 master - 0 1617337335000 0 connected
d1ca7e72126934ef569c4f4d34ba75562d36068f 192.168.0.150:6379@16379 master - 0 1617337337289 14 connected

​ 目前node4的6379和6380並未建立槽位,也沒有和其他節點建立聯系,所以不能進行任何讀寫操作。

進行擴容

​ 使用redis-trib.rb工具對新節點進行擴容,大體流程是每個節點拿出一部分槽位分配給node4:6379。

image-20210402161015475

​ 在槽位遷徙時會帶着數據一起遷徙,這並不會影響正常業務,屬於熱擴容。

​ 首先要做4分片的規划,每個節點共分4096個槽位:

$ python3
>>> divmod(16384,4)
(4096, 0)

​ 接下來開始進行擴容,由於我們只在node1上裝了ruby環境,所以在node1上執行:

$ cd /usr/local/redis_cluster/redis-6.2.1/src/ 

# 舊版Redis這里以腳本名開頭 redis-trib.rb,並且不需要添加--cluster參數
$ redis-cli --cluster reshard 192.168.0.120 6379 

# 你需要分配多少?
How many slots do you want to move (from 1 to 16384)? 4096

# 你要給哪一個集群節點分配插槽?我是給node4節點的6379
what is the receiving node ID? d1ca7e72126934ef569c4f4d34ba75562d36068f

# 你要從哪些集群節點給node4節點6379分配插槽呢?可以輸入all代表所有節點平均分配
# 也可以輸入所有節點node-ID以done結束,我這里是所有節點,需要node1:6379、node2:6379、node3:6379
# 共拿出4096的槽位分配給node4:6379
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.
Source node #1: all

​ 經過漫長的等待,終於擴容完成了:

$ redis-cli -h node1 -p 6379 cluster nodes

192.168.0.150:6379@16379 master - 0 1617337961000 14 connected 0-1364 5461-6826 10923-12287
192.168.0.130:6379@16379 master - 0 1617337967569 3 connected 12288-16383
192.168.0.120:6379@16379 myself,master - 0 1617337967000 12 connected 1365-5460
192.168.0.140:6379@16379 master - 0 1617337963000 13 connected 6827-10922

​ 查看集群節點信息,發現他分配的並不是特別均勻,只要誤差在2%以內,就算正常范圍。

主從修改

​ 如果你在線上生產環境中對Redis集群進行了擴容,一定要注意主從關系。

​ 手動的對主從關系進行校正,這里不再進行演示。

集群縮容

移除節點

​ 下線節點時,節點如果持有槽必須指定將該槽遷徙到別的節點。

​ 在槽遷徙時,數據也會一並遷徙,並不影響業務。

image-20210402123903685

​ 同時,當槽遷徙完成后,可在集群中對該節點進行遺忘。

進行縮容

​ 這里縮容對象還是node4:6379,它本身具有4096個插槽,我們需要分別把4096個插槽移動到node1:6379、node2:6379、node3:6379上。

image-20210402161216191

計算每個節點分多少:

$ python3
>>> divmod(4096,3)
(1365, 1)

# 2個分1365 1個分1366

​ 開始縮容,以下操作做3次:

$ cd /usr/local/redis_cluster/redis-6.2.1/src/ 

# 舊版Redis這里以腳本名開頭 redis-trib.rb,並且不需要添加--cluster參數
$ redis-cli --cluster reshard 192.168.0.120 6379

>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

# 你想移動多少插槽?2次1365,1次1366
How many slots do you want to move (from 1 to 16384)? 1365

# 你想由誰來接收? node1:6379、node2:6379、node3:6379的node-id
What is the receiving node ID? 282358c2fb0c7c16ec60f2c4043b52a0eb91e19f

# 你想指定那個節點發送插槽?
Please enter all the source node IDs.
  Type 'all' to use all the nodes as source nodes for the hash slots.
  Type 'done' once you entered all the source nodes IDs.

# node4:6379的node-id
Source node #1: d1ca7e72126934ef569c4f4d34ba75562d36068f
Source node #2: done

# 輸入yes
Do you want to proceed with the proposed reshard plan (yes/no)? yes

​ 擴容完成后檢查集群狀態:

$ redis-cli -h node1 -p 6379 cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:8
cluster_size:3
cluster_current_epoch:17
cluster_my_epoch:15
cluster_stats_messages_ping_sent:17672
cluster_stats_messages_pong_sent:26859
cluster_stats_messages_meet_sent:7
cluster_stats_messages_auth-req_sent:10
cluster_stats_messages_auth-ack_sent:2
cluster_stats_messages_update_sent:23
cluster_stats_messages_mfstart_sent:1
cluster_stats_messages_sent:44574
cluster_stats_messages_ping_received:17283
cluster_stats_messages_pong_received:24508
cluster_stats_messages_meet_received:5
cluster_stats_messages_fail_received:1
cluster_stats_messages_auth-req_received:2
cluster_stats_messages_auth-ack_received:5
cluster_stats_messages_mfstart_received:1
cluster_stats_messages_received:41805

​ 查看node4:6379是否有未分配出去的插槽:

$ redis-cli -h node1 -p 6379 cluster nodes

# 沒有占據任何槽位、已被全部分配出去
d1ca7e72126934ef569c4f4d34ba75562d36068f 192.168.0.150:6379@16379 master - 0 1617349187107 14 connected
f3dec547054791b01cfa9431a4c7a94e62f81db3 192.168.0.150:6380@16380 master - 0 1617349182874 0 connected

進行下線

​ 現在就可以對node4:6379與node4:6380進行下線了,任意登錄集群中某一節點,輸入以下命令:

$ redis-cli -h node1 -p 6379 cluster FORGET d1ca7e72126934ef569c4f4d34ba75562d36068f
$ redis-cli -h node1 -p 6379 cluster FORGET f3dec547054791b01cfa9431a4c7a94e62f81db3

​ 檢查是否以從節點中移除:

$ redis-cli -h node1 -p 6379 cluster nodes

ff53e43f9404981a51d4e744de38004a5c22b090 192.168.0.130:6380@16380 slave 7a7392cb66bea30da401d2cb9768a42bbdefc5db 0 1617349417000 17 connected
d645d06708e1eddb126a6c3c4e38810c188d0906 192.168.0.120:6380@16380 slave 282358c2fb0c7c16ec60f2c4043b52a0eb91e19f 0 1617349415310 16 connected
282358c2fb0c7c16ec60f2c4043b52a0eb91e19f 192.168.0.130:6379@16379 master - 0 1617349414244 16 connected 5461-6825 12288-16383
c71b52f728ab58fedb6e05a525ce00b453fd2f6b 192.168.0.120:6379@16379 myself,master - 0 1617349414000 15 connected 0-5460
7a7392cb66bea30da401d2cb9768a42bbdefc5db 192.168.0.140:6379@16379 master - 0 1617349416000 17 connected 6826-12287
6a627cedaa4576b1580806ae0094be59c32fa391 192.168.0.140:6380@16380 slave c71b52f728ab58fedb6e05a525ce00b453fd2f6b 0 1617349417761 15 connected

​ 至此,node4:6379以及node4:6380成功下線。

主從修改

​ 如果你在線上生產環境中對Redis集群進行縮容,一定要注意主從關系。

​ 手動的對主從關系進行校正,這里不再進行演示。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM