Last Updated on

前言

 redis cluster官方的一个分布式集群方案,实现了主从替换,自动分发存取,去中心化,弹性伸缩等,常用于普通的主从哨兵集群无法满足的互联网公司的大量数据情况。

在此之前,我也介绍了redis的单机和主从哨兵集群:

在开始redis cluster集群搭建之前,我们得先了解以下redis cluster的架构:

架构大致如上图(画的简陋,见谅见谅),整个架构最低节点数为6个,分为3主3从,3个主节点之间,通过分片,连为一个整体,通过分片将数据分发存储在多个主节点上,每个主节点有都有一个从节点作为备份服务。

此集群架构有如下特点:

  • 主从备份,自动故障转移,保证了服务的高可用,一个主节点的从节点可以是任意多个。
  • 数据采用哈希槽的方式进行分配,所有主节点平分16384个slots槽位,连起来为一个完整的不重复数据,只通过从节点进行数据冗余高可用。
  • 这些槽的数据,丢失任意其中一段,都会进入fail状态, 集群整体不可用。
  • 客户端连接任一主节点,即可访问整个集群的数据,若数据不在当前主节点上,会通过内部算法找到存放数据的机器并获取数据返回。
  • 可新增删除主节点,以提高减少存储容量

下面就详细的记录如何搭建redis cluster分布式集群。

正文

下面就详细的记录以下,如果搭建redis cluster分布式集群:

1. 环境准备

 6台centos7 服务器,ip分别为:

  • 192.168.0.1
  • 192.168.0.2
  • 192.168.0.3
  • 192.168.0.4
  • 192.168.0.5

为以上每台服务器安装redis最新版,redis cluster集群是redis官方至3.0版本后新增的集群方案,最好用redis最新版才且需要用源码安装,安装详细教程可参考我另一篇博文:

《Centos7 Redis的安装与简单使用》

2. 修改配置文件,启动服务

分别在6台服务器上,修改redis配置文件。

# 修改配置文件中下列这些项
$ vim /etc/redis/6379.conf
-------------------------------------------------------------
# 放开连接限制
bind 0.0.0.0

# 开启守护进程
daemonize yes

# 保护模式,默认开启,开启的话,必须设置bind和密码中的一个,不然无法访问。
# 我这里设置了bind 0.0.0.0,所以可以正常访问,即使不设置密码。
protected-mode yes

# 我这里作为缓存服务器,所以注释掉持久化设置
# save 900 1
# save 300 10
# save 60 10000

# 最大内容限制
maxmemory 2gb

# 开启cluster集群
cluster-enabled yes

# 自动移集群配置文件路径,会自动生成
cluster-config-file /etc/redis/nodes.conf

# cluster集群节点超时时间,默认为12秒,为 i这里设的10秒
cluster-node-timeout 10000
-------------------------------------------------------------

# 重启服务
$ systemctl restart redis_6379

# 防火墙开放6379端口。
$ firewall-cmd --add-port=6379/tcp --permanent
$ firewall-cmd --reload

3. 创建集群

随便选择一个服务器进行操作,使用工具创建集群。

在网上的很多文章,创建cluster集群,是使用源码中的redis-trib.rb这个工具来实现,使用这个工具需要ruby语言支持,所以需要安装ruby和rubygem,由通过gem安装redis插件后,才能使用redis-trib.rb这个工具。

但是至redis5.0之后摒弃了该工具,将搭建集群的功能合并到了redis-cli上,进一步简化了搭建redis cluster的过程:

# 创建集群,通过--cluster-replicas指定每个master节点配几个从节点
# 创建集群时,要确保每个redis服务中都没有数据,时空的,不然会无法创建。
$ redis-cli --cluster create 192.168.0.1:6379 192.168.0.2:6379 192.168.0.3:6379 192.168.0.4:6379 192.168.0.5:6379 192.168.0.6:6379 --cluster-replicas 1

# 最后出现这样的提示,则为成功创建
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.

# 检查集群状态,可以看到集群中所有主节点和主节点的槽位
$ redis-cli --cluster check 127.0.0.1:6379
# 出现如下输出,可以看到每个master几点的槽位数,和从节点数,还有key的数量。
192.168.0.1:6379 (03bdedd6...) -> 0 keys | 5461 slots | 1 slaves.
192.168.0.2:6379 (aa6cebab...) -> 0 keys | 5462 slots | 1 slaves.
192.168.0.3:6379 (f5157abc...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 3 masters.
0.00 keys per slot on average.

ok。就这么简单集群搭建就完成了。

4. 新增/删除节点

redis cluster集群作为具备伸缩性的分布式集群,随着数量的变化,增删节点为常用操作,下面记录一下,如果在对集群增删节点:

# 增加节点,新节点写在前面,后面要写上原有集群中的任一现存的主节点,这样才能找到你要在哪个集群中添加节点
# 同时添加多个节点时,同样通过--cluster-replicas指定每个master节点配几个从节点
$ redis-cli --cluster add-node 192.168.0.7:6379 192.168.0.1:6379


# 添加成功后,检查现有集群,会发现新增的master节点,没有分配槽位
$ redis-cli --cluster check 127.0.0.1:6379
# 结果如下
192.168.0.1:6379 (03bdedd6...) -> 0 keys | 5461 slots | 1 slaves.
192.168.0.2:6379 (aa6cebab...) -> 0 keys | 5462 slots | 1 slaves.
192.168.0.7:6379 (24663289...) -> 0 keys | 0 slots | 0 slaves.
192.168.0.3:6379 (f5157abc...) -> 0 keys | 5461 slots | 1 slaves.
[OK] 0 keys in 4 masters.
0.00 keys per slot on average.


# 为新节点分配槽位
$ redis-cli --cluster reshard 192.168.0.7:6379

# 会出现下面的问题,需要手动指定:
# 要为新节点分配多少槽位,我这里设的1000
How many slots do you want to move (from 1 to 16384)? 1000

# 接受槽位的节点ID号
What is the receiving node ID? 2466328994612903acba7057d45a6caf8d911869

# 选择模式,all:从所有其他节点上平均分配。 done:指定从固定源节点上分配槽位
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

# 确定执行分配吗? 填yes
Do you want to proceed with the proposed reshard plan (yes/no)? yes



# ok,分配完成,再check检查,就能看到新节点上有了1000个槽位。


# 下面记录如何删除节点
# 删除从节点的话,直接删除即可,后跟节点的id
$ redisc-cli --cluster del-node 192.168.0.4:6379 be4c381f5f79939437d10a84e4fbc371588413f9
>>> Removing node be4c381f5f79939437d10a84e4fbc371588413f9 from cluster192.168.0.4:6379
>>> Sending CLUSTER FORGET messages to the cluster...
>>> SHUTDOWN the node.

# 删除主节点前,则需要先讲主节点上的槽位转移到别的节点上,才能删除
$ redis-cli --cluster reshard 192.168.0.7:6379 
# 输入要删除的节点上的所有槽位,我这里删除上面新增的节点,槽位位1000
How many slots do you want to move (from 1 to 16384)? 1000

# 输入要接受这些槽位的节点id
What is the receiving node ID? aa6cebab71db2f18163f4831c9033175de162133

# 输入要删除的节点的id,再输入done。即表示从要删除的节点移动指定数量槽位到接受槽位的节点
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: 2466328994612903acba7057d45a6caf8d911869
Source node #2: done

# 确定执行分配吗? 填yes
Do you want to proceed with the proposed reshard plan (yes/no)? yes

# 然后删除主节点,后跟节点id
$ redis-cli --cluster del-node 192.168.0.7:6379 2466328994612903acba7057d45a6caf8d911869

OK,到此就记录演示了如何在集群上新增,删除节点,分配槽位。以此来管理redis cluster集群。

注意: 删除节点后,对应的节点的redis服务则会停止运行,但即使服务重新启动后,也不会自动恢复到集群中,而需要手动将节点重新添加到集群中。如果slave节点删除后,再重启,还是slave节点,会复制在集群中指定的master节点的数据,但是并不是集群的一员,只是一个独立的slave节点。如何要将此slave节点重新加入集群,需要清空数据,重新以初始化的配置启动,再加入集群。

5. 简单试用测试集群

集群正常搭建后,我们来测试一下,集群的功能是否正常运行。测试思路为下:

连接集群其中一个主节点,插入数据,查看数据保存在什么节点上,连接别的主节点,查询数据,是否能正常获取到数据,查看数据从节点,是否有其主节点数据。

# 连接集群节点,连接clster集群时,需要添加-c参数
$ redis-cli -c -h 127.0.0.1 -p 6379
# 设置一个abc的key,如下:
127.0.0.1:6379> set abc "cluster is ok"
-> Redirected to slot [7638] located at 192.168.0.2:6379
OK


# 看到其讲数据保存到了7638槽位,在192.168.0.2:6379节点
# 我们连接别的节点,看看能否获取到数据
$ redis-cli -c -h 192.168.0.1 -p 6379
# 获取数据正常,ok!
192.168.0.1:6379> get abc
-> Redirected to slot [7638] located at 192.168.0.2:6379
"cluster is ok"

# 查看从节点,连接从节点时,不能使用-c参数,只要使用了-c参数,则是连接集群,即使连接的是集群中的从节点,也一样能够获取到集群中的数据
$ redis-cli -h 192.168.0.5 -p 6379
192.168.0.5:6379>get abc
# 报错,从0.3的主节点的从节点上
(error) MOVED 7638 192.168.0.2:6379
# 查看keys,发现为空
192.168.0.5:6379> keys *
(empty list or set)

# 192.168.0.2主节点的从节点是192.168.0.4,在上面示范删除节点的时候,把它给删了,所以我又重新初始化,将其加入了集群,加入后会自动同步主节点的数据。
$ redis-cli -h 192.168.0.4 -p 6379
# 证明数据同步到了从节点,有abc的keys
192.168.0.4:6379> keys
1) "abc"

# 但是获取数据值时,依然无法获取,提示通过集群主节点获取数据。
192.168.0.4:6379> get abc
(error) MOVED 7638 192.168.0.2:6379

# 我们再试一下,指连主节点,是否能获取到数据
$ redis-cli -h 192.168.0.2 -p 6379
192.168.0.2:6379> get abc
"cluster is ok"     # 能获取到数据

ok,测试完成。进过我们的测试,证明了集群的完好运行,也发现了一些需要注意的地方:

连接集群内任意节点,都可以获取到完整的集群数据。如果直接连接服务,不连集群,则只能在master节点上获取到当前master节点上有的数据,slave节点都是无法获取数据的。

结束

ok,到此就完成了redis cluster分布式集群的搭建和节点的增删。

有什么问题,欢迎留言