redis优化系列(九)Redis cluster原理及扩容操作

该系列博文之上一篇:传送门 走你


本篇博文使用的素材又增加了2个文件:redis-config-6397-6398.zip

温馨提示:

下载以上提供的压缩文件并将解压后的两个文件(nodes-6397.conf、nodes-6398.conf)上传到服务器中的 /usr/docker/redis/config 目录中,如果你不是按照本系列博文的路径,那自行上传到你自己对应的路径即可


/usr/docker/redis/config 目录中的文件相比之前就会多了2个文件,目录中的文件如下所示:

r1.png


Redis cluster的简单原理介绍

1、节点通信

在分布式存储中需要提供维护节点元数据信息的机制,所谓元数据是指:节点负责哪些数据,是否出现故障等状态信息,Redis 集群采用  Gossip(流言)协议,Gossip 协议工作原理就是节点彼此不断通信交换信息,一段时间后所有的节点都会知道集群完整的信息,这种方式类似流言传播。


集群中的每个节点都会单独开辟一个 TCP 通道,用于节点之间彼此通信,通信端口号在基础端口上加10000。

    1)每个节点在固定周期内通过特定规则选择几个节点发送 ping 消息。

    2)接收到 ping 消息的节点用 pong 消息作为响应。


集群中每个节点通过一定规则挑选要通信的节点,每个节点可能知道全部节点,也可能仅知道部分节点,只要这些节点彼此之间可以正常通信,最终它们会达到一致的状态。当节点出故障、新节点加入、主从角色变化、槽信息变更等事件发生时,通过不断的 ping/pong 消息通信,经过一段时间后所有的节点都会知道整个集群全部节点的最新状态,从而达到集群状态同步的目的。


以上就是redis集群的简单原理介绍,没有更深入。


集群的伸缩

Redis 集群提供了灵活的节点扩容和收缩方案。在不影响集群对外服务的情况下,可以为集群添加节点进行扩容也可以下线部分节点进行缩容。

r1.jpg


槽和数据与节点的对应关系:

当主节点分别维护自己负责的槽和对应的数据,如果希望加入1个节点实现集群扩容时,需要通过相关命令把一部分槽和数据迁移给新节点。

r2.jpg

上面图里的每个节点把一部分槽和数据迁移到新的节点6385,每个节点负责的槽和数据相比之前变少了从而达到了集群扩容的目的,集群伸缩=槽和数据在节点之间的移动。

扩容操作

扩容的主要目的是为了分担集群中的压力。


扩容是分布式存储最常见的需求,Redis 集群扩容操作可分为如下步骤:

1)准备新节点。

2)加入集群。

3)迁移槽和数据。


①、准备新节点

需要提前准备好新节点并运行在集群模式下,新节点建议跟集群内的节点配置保持一致,便于管理统一。


容器名称     容器IP地址        映射端口号                服务运行模式

redis-master4     172.50.0.5        6397->6397     master

redis-slave4     172.30.0.5        6398->6398     slave


②、加入集群

通过redis-trib.rb add-node    127.0.0.1:6397    127.0.0.1:6391   实现节点添加

                                               要加入的节点      集群中的节点


③、迁移槽和数据

加入集群后需要为新节点迁移槽和相关数据,槽在迁移过程中集群可以正常提供读写服务,迁移过程是集群扩容最核心的环节,继续往下看。


槽是 Redis 集群管理数据的基本单位,首先需要为新节点制定槽的迁移计划,确定原有节点的哪些槽需要迁移到新节点。迁移计划需要确保每个节点负责相似数量的槽,从而保证各节点的数据均匀,比如之前是三个节点,现在是四个节点,把节点槽分布在四个节点上。

r3.jpg


槽迁移计划确定后开始逐个把槽内数据从源节点迁移到目标节点

r4.jpg

数据迁移过程是逐个槽进行的

流程说明:

    1)对目标节点发送导入命令,让目标节点准备导入槽的数据。

    2)对源节点发送导出命令,让源节点准备迁出槽的数据。

    3)源节点循环执行迁移命令,将槽跟数据迁移到目标节点。

r5.jpg


redis-trib.rb工具提供了槽重分片功能,命令格式如下:

redis-trib.rb reshard host:port --from <arg> --to <arg> --slots <arg> --yes --timeout <arg> --pipeline <arg>

参数说明:

host:port:必传参数,集群内任意节点地址,用来获取整个集群信息。

--from:制定源节点的 id,如果有多个源节点,使用逗号分隔,如果是all源节点变为集群内所有主节点,在迁移过程中提示用户输入。

--to:需要迁移的目标节点的id,目标节点只能填写一个,在迁移过程中提示用户输入。

--slots:需要迁移槽的总数量,在迁移过程中提示用户输入。

--yes:当打印出 reshard 执行计划时,是否需要用户输入yes确认后再执行 reshard。

--timeout:控制每次 migrate 操作的超时时间,默认为60000毫秒。

--pipeline:控制每次批量迁移键的数量,默认为10。


实战之redis cluster集群扩容操作

注意:下面的redis集群扩容操作都是使用redis-trib.rb管理工具来进行操作的。


为什么要使用这个工具来操作?

答:因为它做了一个容错处理,假设这个节点在集群中已经存在的话,我们在执行加入集群的这个操作的话,可能会造成一些数据的问题。生产环境下除非万不得已,否则一定、必须要使用管理工具来进行操作,除非管理工具没有提供你要操作的功能,那么可以用原生的集群的命令去操作。


前面搭建redis集群的博文中已经创建了redis集群 这次就是给之前已经搭建好的redis集群进行扩容,在这里我们再次新增2台redis节点(一主一从),加入到之前搭建好的redis集群中


1、准备创建2台redis节点

#创建一台主节点 容器名字为:redis-master4     端口号为:6397
docker run  -itd  --name redis-master4 -v /usr/docker/redis/config:/config --net redis-cluster_redis-master -e PORT=6397 -p  6397:6397 -p 16397:16397 --ip 172.50.0.5 redis-cluster 


#创建一台从节点 容器名字为:redis-slave4     端口号为:6398
docker run  -itd  --name redis-slave4 -v /usr/docker/redis/config:/config --net redis-cluster_redis-slave -e PORT=6398 -p  6398:6398 -p 16398:16398 --ip 172.30.0.5 redis-cluster


/****************主redis节点操作****************/

#进入redis-master4这台容器里面启动redis服务
docker exec -it redis-master4 bash

#启动redis服务,并在后台运行
redis.sh &

#可以使用netstat命令来查看端口是否已经存在
netstat -apn | grep 6397


/****************从redis节点操作****************/

#进入redis-slave4这台容器里面启动redis服务
docker exec -it redis-slave4 bash

#启动redis服务,并在后台运行
redis.sh &

#可以使用netstat命令来查看端口是否已经存在
netstat -apn | grep 6398


2、将创建的2台redis节点加入到集群当中

#进入集群中的任意一台redis节点,这里我进入redis-slave3这台redis节点容器里
docker exec -it redis-slave3 bash

#通过redis-trib.rb工具中的add-node命令将6397和6398这2台redis节点容器加入到6391的redis集群中
redis-trib.rb add-node 119.3.220.26:6397 119.3.220.26:6391 
redis-trib.rb add-node 119.3.220.26:6398 119.3.220.26:6391 

#如果提示bash: /usr/bin/redis-trib.rb: Permission denied,权限问题,则先赋予执行权限chmod +x /usr/bin/redis-trib.rb,然后再次执行以上命令

示例截图如下:

r2.png

r3.png

它会自动的去帮我们在其它的节点之间来进行通讯


3、使用这台redis节点的客户端连接上redis服务,然后使用cluster nodes命令来查看刚刚加入的6397和6398两台redis节点,redis-trib.rb工具是否为我们自动分配好了主从关系

redis-cli -p 6396

cluster nodes

示例截图如下:

r4.png

由上图可以看到,并没有为我们自动分配好主从关系,并且刚加入集群中的6397和6398这2台redis节点的角色身份都是master(主节点),主从关系的配置需要我们自己来操作,这个在下面说如何配置。


4、迁移槽和数据的简单说明(也就是迁移操作的简单说明)


这里把6397这台redis节点作为master


之前我们集群中有3台master节点,加入一台新的redis节点,那就是4台Redis节点,4台的话平均每一台redis节点中会有4096个槽,4096如何计算出来的?16384 / 4 = 4096。 最好是将16384个槽平均分配给集群中的每一台redis节点


如果你某一台的redis节点性能比较好,也可以让那台性能好的redis节点承载更多的槽,这种操作也是允许的。


大概迁移流程说明:(往上翻,上面有具体的迁移槽和数据的流程图以及文字说明)

①、准备好目标节点和源节点,目标节点指的是 新加入集群中的节点(这里就是6397),源节点指的是 你要将之前的老的一些节点的一部分的槽分配给新加入集群中的节点,这些就是源节点。

②、导入数据槽以及迁移多少个键(键 指的就是redis中的key),一个数据槽里面可能会存在1个、10个、100个、1000个、10000个、100000个......N多个键。

③、它会去计算我到底要导入多少个key,导入到我们这个新加入的节点里面去,计算好了之后它就会开始执行迁移了,直到全部迁移完毕。

④、迁移数据是循环执行迁移的,也就是一条一条的去进行迁移,并不是一次性全部迁移完毕的。


5、开始使用命令执行迁移操作

#使用redis-trib.rb工具中的reshard命令来执行迁移操作

redis-trib.rb reshard 119.3.220.26:6397  
#上面这个6397可以换成6391、6392、6393......等,只要是集群中的任意一台redis节点都可以的。

示例截图如下:

r5.png

从已上图中看出,打印出集群每个节点信息后,reshard 命令需要确认迁移的槽数量,这里我们根据节点个数输入对应的要迁移多少个槽的值,这里我们是4096个槽。

示例截图如下:

r6.png

上图中的 What is the receiving node ID?

表示 你要输入某个节点的节点 ID 作为目标节点,目标节点只能指定一个,这里我们要迁移到6397那台redis节点中,而6397的节点ID在这里是:50849d38117989c6fa5837119fba3554911f035d

示例截图如下:

r7.png

之后输入源节点的 ID,这里分别输入相应的节点 ID 最后用 done 表示结束(完成)。

示例截图如下:

r8.png


然后继续回车之后,数据迁移之前会打印出所有的槽从源节点到目标节点的计划。

示例截图如下:

r9.png


上面截图中确认计划无误后输入 yes 开始执行迁移工作,迁移过程中redis-trib.rb工具会打印出每个槽迁移的进度。

示例截图如下:

r10.png

r11.png


迁移完毕后可以使用redis-trib.rb reshard 119.3.220.26:6379命令查看集群中的节点信息

示例截图如下:

r12.png

从以上截图中可以看到已经成功给6397这台redis节点迁移了4096个槽,至此 我们的redis节点扩容操作已经完成了,就剩下一个设置主从关系的操作了。


6、设置主从操作

redis-trib.rb工具除了在创建集群的时候会帮我们自动设置主从关系之外,类似于这种扩容操作就没有帮我们自动设置主从了,这里设置主从只能使用redis原生命令去设置主从关系

注意:再次强调,设置主从要在从节点上进行设置

命令如下:

#连接上从节点的redis 这里也就是6398这台redis节点
redis-cli -h 119.3.220.26 -p 6398

#cluster replicate 主节点ID 命令来设置主从关系,这里的主节点ID就是6397那台redis的节点ID 
cluster replicate 50849d38117989c6fa5837119fba3554911f035d

示例截图如下:

r2.png

加上上面第6步设置主从的操作,我们完整的redis集群扩容操作算是彻底完成了。


7、迁移过程中的其它相关事项解答:

①、迁移过程中,不会影响集群的其它操作等,比如你在集群中执行相关指令,依然是可以的。迁移过程中依然是可以往redis中写入数据的。

②、槽对应的数据也会被迁移到目标节点中。

③、本文中的119.3.220.26这个IP地址换成你自己服务器上的公网IP地址。。本文使用的都是公网IP地址来进行节点与节点之间的网络通信的。


redis-trib.rb工具中的其它命令示例

rebalance命令:平衡集群节点中的slot(槽)数量

格式:redis-trib.rb rebalance ip:port 


就拿我们上面刚刚扩容完成的集群做实验吧,命令示例如下:

redis-trib.rb rebalance  119.3.220.26:6391  (6391、6392、6393、6394、6395.......都行,只要是集群中的任意一台都可以,不是非带要6391,可以改成集群中的任意一台节点)

示例截图如下:

r1.png

由于我们这里迁移的时候是按照平均数来迁移的槽的数量,所以这里提示误差在百分之2,不需要去平衡。如果你是不平衡的话,可以使用它去做这么一个平衡的操作,然后又会开始进行迁移操作等。。



别为了那些不属于你的观众,去演绎不擅长的人生    --【遇见未知的自己】



声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。

扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

精彩评论

全部回复12人评论7,777人参与