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集群进行缩容,必定要注意主从关系。

​ 手动的对主从关系进行校订,这里再也不进行演示。

相关文章
相关标签/搜索