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

安裝介紹

​ redis-trib.rb是一款由Redis官方提供的集羣管理工具,可以大量減小集羣搭建的時間。node

​ 除此以外,還可以簡化集羣的檢查、槽遷徙、負載均衡等常見的運維操做,可是使用前必需要安裝ruby環境。python

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

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驅動,經測試沒有任何問題:vim

gem install redis -v 3.3.5

​ 另外,在新版Redis中,redis-trib.rb工具的功能都被集成在了redis-cli裏,但依然須要ruby環境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-1638三、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:637九、node2:637九、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:637九、node2:637九、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:637九、node2:637九、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集羣進行縮容,必定要注意主從關係。

​ 手動的對主從關係進行校訂,這裏再也不進行演示。

相關文章
相關標籤/搜索