redis集群重新分配插槽 redis集群重建_redis集群重新分配插槽


模式二:Cluster集群

由于redis集群的理论还有实践都比较复杂,所以我们将把实操和理论分为两篇文章介绍,这篇文章首先介绍实操环节。

Redis3.0之后,节点之间通过去中心化的方式提供了完整的sharding(分片),replication(复制),failover(故障迁移)解决方案,成为redis-cluster

Redis 集群是一个可以在多个 Redis 节点之间进行数据共享的设施

并且集群特性不支持跨节点的keys命令,并且通过分区来保证当一个节点失效时其他节点可以继续工作。

redis集群的优势:

  • 自动分割数据到不同的节点上。
  • 整个集群的部分节点失败或者不可达的情况下能够继续处理命令

redis集群并没有使用一致性hash,而是引入了哈希槽(slot)的概念,redis集群共有16384个slot,每一个key通过一定的计算方式分配到不同的slot上,然后每一个节点负责一部分的slot.

举例,比如当前集群有三个节点,那么:

  • 节点 A 包含 0 到 5500号哈希槽.
  • 节点 B 包含5501 到 11000 号哈希槽.
  • 节点 C 包含11001 到 16384号哈希槽.

这种结构的优点就是很容易的添加或删除节点,比如我想新添加一个节点D,我们需要从A,B,C中的部分槽转移到D,如果我想移除节点A,需要将A中的槽移到B和C节点上,然后将没有任何槽的A节点从集群中移除即可.由于从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加删除或者改变某个节点的哈希槽的数量都不会造成集群不可用的状态.

搭建并使用redis集群:

修改redis.windows.conf配置


port 6380
cluster-enabled yes  //开启集群模式
cluster-config-file nodes-6380.conf //保存节点配置文件的路径
cluster-node-timeout 15000 //节点超时时间


每个实例都按照对应的端口号进行修改,然后将六个实例都运行起来

集群启动需要用到命令行工具redis-trib,而这个工具是一个ruby程序,因此我们需要安装ruby,

下载地址:http://dl.bintray.com/oneclick/rubyinstaller/rubyinstaller-2.2.4-x64.exe

下载下来后按照步骤安装,最后一步勾选全部如图:


redis集群重新分配插槽 redis集群重建_故障转移集群重建_02


下载ruby环境redis驱动

下载地址:https://rubygems.org/gems/redis/versions/3.2.2

如图:


redis集群重新分配插槽 redis集群重建_故障转移集群重建_03


将下载下来的文件放入ruby安装目录下,如图:


redis集群重新分配插槽 redis集群重建_redis集群_04


安装该驱动,命令如下:


gem install --local C:Ruby22-x64redis-3.2.2.gem


如图表示成功:


redis集群重新分配插槽 redis集群重建_redis_05


环境准备完毕,我们需要在redis的github上找到redis-trib.rb文件(集群命令工具 )

链接:https://github.com/microsoftarchive/redis/tree/3.0/src

在src文件夹下有如下文件:


redis集群重新分配插槽 redis集群重建_数据_06


copy下来后放在redis文件夹下如图:


redis集群重新分配插槽 redis集群重建_故障转移集群重建_07


此时一切准备就绪,脚本创建集群


redis-trib.rb create --replicas 1 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6382 127.0.0.1:6383 127.0.0.1:6384 127.0.0.1:6385


选项–replicas 1 表示我们希望为集群中的每个主节点创建一个从节点

执行后出现如图


redis集群重新分配插槽 redis集群重建_redis集群重新分配插槽_08


在输入yes后,运行如下表示成功:


redis集群重新分配插槽 redis集群重建_redis集群重新分配插槽_09


上图表示集群中的 16384 个槽都有至少一个主节点在处理, 集群运作正常。

此时我们查看集群情况,如图:


redis集群重新分配插槽 redis集群重建_故障转移集群重建_10


redis集群重新分配插槽 redis集群重建_故障转移集群重建_11


从上图我们可以看出,redis目前模式是cluster模式,自动分配6383为从节点。

我们简单测试下set功能,如图


redis集群重新分配插槽 redis集群重建_故障转移集群重建_12


上图我们可以看出我们在6380set数据在从节点6383以及另外的6382节点都可以查看到

TODO:在启动集群的时候可能会遇到如下报错,此时我们需要在各个节点上执行下以下命令:然后再重新启动就好了


redis集群重新分配插槽 redis集群重建_数据_13


redis集群重新分配插槽 redis集群重建_数据_14


集群重新分片

现在, 让我们来试试对集群进行重新分片操作

redis-trib.rb reshard 127.0.0.1:6380命令进行重新分片。如下几张图


redis集群重新分配插槽 redis集群重建_redis_15


下图看出开始迁移:


redis集群重新分配插槽 redis集群重建_数据_16


从其他两个主节点开始分slot给6380,如图:


redis集群重新分配插槽 redis集群重建_redis集群重新分配插槽_17


重新分片完成后我们查看集群情况,如图


redis集群重新分配插槽 redis集群重建_redis集群_18


可以清楚看到slot分配和之前有所不同

测试故障转移

我们首先查看集群的节点情况,如图:


redis集群重新分配插槽 redis集群重建_数据_19


可以看出6380,6381,6382为主节点,我们测试6380宕机,自动进行故障迁移。

在6380节点执行debug segfault命令,让主节点崩溃,如图


redis集群重新分配插槽 redis集群重建_redis_20


此时我们可以看到6383自动成为了主节点,如图对比可以看出效果:


redis集群重新分配插槽 redis集群重建_故障转移集群重建_21


我们再将6380重启,已启动我们就可以看到6380成为了6383的从节点,同时在同步主节点的数据,如图:


redis集群重新分配插槽 redis集群重建_故障转移集群重建_22


手动故障迁移

有的时候在主节点没有任何问题的情况下强制手动故障转移也是很有必要的,比如想要升级主节点的Redis进程,我们可以通过故障转移将其转为slave再进行升级操作来避免对集群的可用性造成很大的影响。

Redis集群使用 CLUSTER FAILOVER命令来进行故障转移,不过要被转移的主节点的从节点上执行该命令 手动故障转移比主节点失败自动故障转移更加安全,因为手动故障转移时客户端的切换是在确保新的主节点完全复制了失败的旧的主节点数据的前提下下发生的,所以避免了数据的丢失。

我们这里由于我们刚刚执行了自动故障迁移,6383目前为主,6380为从,我们这次执行手动故障迁移,同样是这个节点,我们在6380从节点直接上面命令,如图:


redis集群重新分配插槽 redis集群重建_redis集群_23


添加一个新节点

添加新的节点的基本过程就是添加一个空的节点然后移动一些数据给它,有两种情况,添加一个主节点和添加一个从节点

先从添加主节点开始.

第一步都是要添加 一个空的节点.同样还是copy一份redis配置,修改下端口号即可,这里我们新增一个6386节点。

6386节点启动成功后,我们执行以下命令将节点加入集群,如图:


redis-trib.rb add-node 127.0.0.1:6386 127.0.0.1:6380


redis集群重新分配插槽 redis集群重建_故障转移集群重建_24


此时我们可以看到6386节点成功加入集群


redis集群重新分配插槽 redis集群重建_故障转移集群重建_25


然后我们此时可以向上面所说的重新分片,向6386节点分配一点slot就可以了。

添加一个从节点

我们接下来添加一个从节点进入集群,同上述一样,复制一份redis文件修改端口号,节点端口号为6387,添加从节点需要执行以下命令:


redis-trib.rb add-node --slave 127.0.0.1:6387 127.0.0.1:6380


结果如下两图:


redis集群重新分配插槽 redis集群重建_redis集群_26


redis集群重新分配插槽 redis集群重建_redis集群_27


这种方式并没有从节点绑在哪个主节点下面,集群会随机分配,我们也可以进行指定,新建6388节点,启动,指令如下:


redis-trib.rb add-node --slave --master-id 87532601dbdcced4cdc6668fdd224d91a7065844 127.0.0.1:6388 127.0.0.1:6380


我们这里指定绑在6381下面,执行之前我们可以看到只有6384是6381的从节点(这里官网上有查专门从节点的命令,不知为何一直失败。。。),执行完毕后我们可以看到6381从节点改变为两个。


redis集群重新分配插槽 redis集群重建_redis集群重新分配插槽_28


redis集群重新分配插槽 redis集群重建_redis集群重新分配插槽_29


redis集群重新分配插槽 redis集群重建_redis_30


移除一个节点

只要使用 del-node 命令即可:

这里我们移除刚刚新增的6388,del-node后面为随意指定一个集群节点,之后为要删除的节点id


redis-trib del-node 127.0.0.1:6380 a6205f7eb6b3e3afa1211b7f80ac11357235e9a6


redis集群重新分配插槽 redis集群重建_redis_31


redis集群重新分配插槽 redis集群重建_故障转移集群重建_32


执行之后可以看到6388节点已经不在集群

这里是移除从节点,我们试一下移除主节点,这里需要注意移除主节点之前需要确保主节点下没有数据,比如我们先移除6381,如图:


redis集群重新分配插槽 redis集群重建_redis集群_33


redis集群重新分配插槽 redis集群重建_redis集群_34


可以看出由于6381是存在slot的,所以执行失败,我们再试着移除6386,6386是我们上面加入的一个新的主节点,我们在加入后并没有分片给它,所以它是不存在数据的,如图


redis集群重新分配插槽 redis集群重建_redis集群_35


redis集群重新分配插槽 redis集群重建_redis_36


上图我们可以看出很顺利的就删除了6386主节点。

从节点的迁移

在Redis集群中会存在改变一个从节点的主节点的情况,需要执行如下命令 :


CLUSTER REPLICATE <master-node-id>


目前我们集群6380存在两个从节点6383和6387


redis集群重新分配插槽 redis集群重建_redis_37


我们将6387迁移到6382上,如图:


redis集群重新分配插槽 redis集群重建_redis集群重新分配插槽_38


在集群中同样存在为了保证基金的高可用性,会存在自动从节点迁移,以保证主节点尽量有一个从节点。

这篇文章我们主要介绍了redis集群的搭建过程,但是具体的集群原理,如怎么分片,怎么检测故障迁移之类的还没有介绍,我们将在下一篇文章介绍。