00-前言
在工作环境中,我们常常被要求配置多种集群,Redis 集群是最常见的入门需要掌握的集群配置方法,在之前的学习中,我们学习掌握了分布式存储的算法,本质上集群的部署就是通过分布式存储算法将数据分发部署好的不同的容器,因此在本篇文章中我们重点学习三主三从的 Redis 集群的配置。
01-集群部署设计
在初步的集群部署中,我们可以设计简单的三主三从流程图,然后针对不同的突发情况,继而再进行优化。
部署集群的大体步骤如下:
- 关闭防火墙+Docker 容器启动
- 新建 6 个容器实例
- 进入一台容器
redis-node-1
,并为 6 台容器制作集群关系 - 链接进一台容器,查看集群状态
02-集群部署操作
容器实例创建
首先需要创建 6 个容器实例,具体流程及命令如下:
docker run -d --name redis-node-1 --net host --privileged=true -v /data/redis/share/redis-node-1:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6381
docker run -d --name redis-node-2 --net host --privileged=true -v /data/redis/share/redis-node-2:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6382
docker run -d --name redis-node-3 --net host --privileged=true -v /data/redis/share/redis-node-3:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6383
docker run -d --name redis-node-4 --net host --privileged=true -v /data/redis/share/redis-node-4:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6384
docker run -d --name redis-node-5 --net host --privileged=true -v /data/redis/share/redis-node-5:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6385
docker run -d --name redis-node-6 --net host --privileged=true -v /data/redis/share/redis-node-6:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6386
以下是对这个命令的分析:
-
docker run
: 这是运行 Docker 容器的基本命令。 -
-d
: 这个选项指定容器以后台模式 (detached) 运行,即容器会在后台运行而不阻塞终端。 -
--name redis-node-1
: 这个选项指定容器的名称为 "redis-node-1"。 -
--net host
: 这个选项指定容器共享宿主主机的网络命名空间,这意味着容器将使用主机的网络配置。 -
--privileged=true
: 这个选项指定容器在特权模式下运行,这允许容器具有更高的系统权限。 -
-v /data/redis/share/redis-node-1:/data
: 这个选项用于挂载主机上的目录到容器内部。具体来说,它将主机上的 "/data/redis/share/redis-node-1" 目录挂载到容器内部的 "/data" 目录。 -
redis:6.0.8
: 这是要运行的 Docker 镜像的名称和版本。在这种情况下,它是 Redis 数据库的版本 6.0.8。 -
--cluster-enabled yes
: 这个选项指定 Redis 在容器内启用集群模式,允许多个 Redis 实例组成集群。 -
--appendonly yes
: 这个选项指定 Redis 使用 AOF(Append-Only 文件)持久化模式,将所有写操作追加到文件中,以增加数据的持久性。 -
--port 6381
: 这个选项指定容器内 Redis 服务器的端口号为 6381。这是 Redis 服务器监听客户端连接的端口。这个命令会创建一个 Redis 容器,以后台模式在主机的网络命名空间下运行,容器具有特权模式,挂载主机上的目录到容器内部,使用 Redis 6.0.8 镜像,启用集群模式和 AOF 持久化,并监听端口 6381。
构建主从关系
创建完成 6 台容器后,我们需要进入主容器,进行主从关系的构建,具体命令如下:
docker exec -it redis-node-1 /bin/bash
redis-cli --cluster create 10.0.16.5:6381 10.0.16.5:6382 10.0.16.5:6383 10.0.16.5:6384 10.0.16.5:6385 10.0.16.5:6386 --cluster-replicas 1
以上命令的作用是命令要创建一个 Redis 集群,要将到集群的 Redis 节点的地址和端口列表。在这里,指定了六个节点,分别是 10.0.16.5 主机上的端口 6381 到 6386,这些节点将成为 Redis 集群的一部分。而`--cluster-replicas 1`指的是每个主节点应该有一个从节点<br />执行完成后,系统输出如下内容,要求我们确认以上配置:![image.png](https://cdn.nlark.com/yuque/0/2023/png/23199109/1699429627979-2a02f480-4d8d-42cf-a978-9e62064b8ddd.png#averageHue=%23201e45&clientId=ucbc5fdfb-4df2-4&from=paste&height=549&id=u8c16852b&originHeight=790&originWidth=1798&originalType=binary&ratio=1.440000057220459&rotation=0&showTitle=false&size=211914&status=done&style=none&taskId=ud2305581-3135-4030-9fca-0455b7df7ee&title=&width=1248.6110614957652) 当我们完成配置的确认后,会出现如下图所示的情况,`**All 16384 slots covered**`**表示槽位**分配正确。<br />![image.png](https://cdn.nlark.com/yuque/0/2023/png/23199109/1699429663966-f7091969-6cdf-47a2-be6a-aec13f8b8444.png#averageHue=%23201e45&clientId=ucbc5fdfb-4df2-4&from=paste&height=682&id=uab4993d8&originHeight=982&originWidth=1477&originalType=binary&ratio=1.440000057220459&rotation=0&showTitle=false&size=205648&status=done&style=none&taskId=ubbfec1c4-211b-4608-a5b5-ebe988e3757&title=&width=1025.6944036870107)
查看集群状态
构建完成好主从关系后,我们可以以主容器redis-node-1
作为切入点,查看集群节点状态,具体命令如下:
docker exec -it redis-node-1 /bin/bash
redis-cli -p 6381
cluster info
cluster nodes
可以看到已经分配了 16384 的槽位,已经知道的节点为 6
并且通过cluster nodes
命令,我们可以清晰地知道节点的主从关系:
通过构造的主从关系如下,需要注意,每次重新创建集群的时候情况可能是不一样的配对关系 :
当我们使用单机版本的命令链接我们的 redis 主机的时候,可能会发生槽位不匹配导致数据无法写入的情况,比如我们连接上node-1
,输入以下命令,会出现报错:
redis-cli -p 6381
set k1 v1
为了解决以上出现的问题,我们需要以集群的方式去链接数据库,然后重新输入数据,会出现如下情况:
redis-cli -p 6381
set k1 v1
03-主从容错切换迁移案例
通过以上操作,我们初步部署了集群化的 redis,在这种情况下,我们要考虑的是假如说有一天机器宕机,我们的主从关系会如何,因此我们通过暂停redis-node-1
机器,并等待心跳包发送完成后进行观察。
可以看到当redis-node-1
挂掉之后,redis-node-5
由 slave 服务器升为 master 服务器。
此时的主从关系更改为如下图所示:
当我们重新启动redis-node-1
后,再次查看主从关系,会发现主从关系已经更改为如下图所示:
03-主从扩容及缩容案例
主从扩容
Redis 集群扩容是指在已经运行的 Redis 集群中增加更多的节点,以增加集群的容量、性能和可用性。这是一种在面临更高负载或需要更多存储容量时扩展 Redis 集群的方式。
Redis 集群中的扩容主要是通过添加新的节点实现的,这些新节点通常是通过添加主节点来存储更多的数据,添加分节点来提供数据的复制和冗余。在主从扩容的过程中,我们主要需要关注的是数据迁移的问题和哈希槽的重新分配问题。
首先我们需要创建两台 redis 容器,进行扩容前的准备,请注意,此时只是启动了容器,和我们的集群暂时是没有关系的:
docker run -d --name redis-node-7 --net host --privileged=true -v /data/redis/share/redis-node-7:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6387
docker run -d --name redis-node-8 --net host --privileged=true -v /data/redis/share/redis-node-8:/data redis:6.0.8 --cluster-enabled yes --appendonly yes --port 6388
然后我们需要进入到redis-node-7
容器中,将其作为master
服务器加入到原集群中,具体命令如下:
redis-cli --cluster add-node IP:6387 IP:6381
# 6387 新加入的集群
# 6381 原集群的老大
此时查看cluster nodes
发现redis-node-7
虽然已经加入集群但是相较于其他的主服务器没有再分配好哈希槽:
因此我们需要重新哈希分配槽号,命令:redis-cli --cluster reshare IP:端口号
,完成槽位的重新分配,执行完毕后槽位完成重新分配,原来三个容器从原来的容器量中匀了点槽位给到第四个槽位。
最后槽位完成分配后,我们需要为主容器redis-node-7
添加从容器redis-node-8
,具体命令如下:
# 具体格式为
redis-cli --cluster add-node 从容器IP:端口 主容器IP:端口 --cluster-slave --cluster-master-id 主容器ID
# 实际操作用例:
redis-cli --cluster add-node 10.0.16.5:6388 10.0.16.5:6387 --cluster-slave --cluster-master-id 1d933eccecd6572f64cba0e0e336b418430a9bd2
至此主存扩容成功,集群情况如下图所示:
主从缩容
通过主从扩容,我们获得了 4 主 4 从的集群案例,有时候我们可能因为流量下降遇到主从缩容的需求,达到按需使用的情景。
主从缩容的步骤如下:
- 先清除从节点,本次实验集群环境中的是
redis-node-8
。
具体命令为如下所示:
# 删除从节点
redis-cli --cluster del-node 从节点IP:Port 从节点ID
- 然后我们需要对槽位进行重新分配,分配完成后再清除主节点,恢复三主三从。
如果我们想要将清楚好的槽号统一分配 给redis-node-1
,代码如下图所示:
redis-cli --cluster reshard 分配给的目标IP:端口
输入完成后需要选择分配的槽位以及选择将槽位分配给谁,具体大致如下图所示:
在此基础上我们实现主容器的删除,至此主从缩容顺利实现:
redis-cli --cluster del-node 删除容器IP:Port 删除容器ID