Redis Cluster 模式是官方支持的功能,也是现在最流行的 redis 集群部署方式。较传统的 Sentinel 模式,不再有单机内存容量、网卡流量限制,真正做到了可以随意扩/缩容。
redis配置启动
dockerfile 如下,这次是直接使用的 yum 安装
# 引用的基础镜像
FROM myos
# 构建默认工作目录
RUN mkdir /home/admin/redis
WORKDIR /home/admin/redis
## 安装redis
RUN yum -y install redis
Redis 的配置文件 redis.conf 需要修改如下内容。
# 集群开关,默认是不开启集群模式
cluster-enabled yes
# 集群配置文件的名称,每个节点都有一个集群相关的配置文件,持久化保存集群的信息
cluster-config-file /home/admin/redis/6379/nodes-6379.conf
# 节点互连超时的阀值。集群节点超时毫秒数
cluster-node-timeout 15000
# 比较slave断开连接的时间和(node-timeout * slave-validity-factor) + repl-ping-slave-period。如果节点超时时间为三十秒, 并且slave-validity-factor为10,假设默认的repl-ping-slave-period是10
cluster-replica-validity-factor 10
# master的slave数量大于该值,slave才能迁移到其他孤立master上
cluster-migration-barrier 1
# 数据目录,数据库的写入会在这个目录。rdb、aof文件也会写在这个目录
dir /home/admin/redis/6379/
# 指定了记录日志的文件
logfile /home/admin/redis/6379/redis.log
下面两种配置方式二选一,因为redis开启了安全性包含的话需要设置密码或者绑定指定ip
# 让用户使用AUTH命令来认证密码,才能使用其他命令
requirepass abc
# 指定 redis 只接收来自于该IP地址的请求
# bind 127.0.0.1
or
# 是否开启保护模式,默认开启。要是配置里没有指定bind和密码。开启该参数后,redis只会本地进行访问,拒绝外部访问
protected-mode no
然后执行 docker 命令构建 docker image 并启动。
##构建镜像
docker build -t myredis .
##启动
docker run -it -p 6301:6301 -p 6302:6302 -p 6303:6303 -p 6304:6304 -p 6305:6305 -p 6306:6306 --name redis \-v /Users/yuman/tools/docker/redis:/home/admin/redis \
-d myredis
进入 Redis 的 Container 后,执行如下命令来开启多个 redis 实例,由于 Redis Cluster 需要至少3个节点,所以我们开启了6个实例(3节点主+备)。
mkdir 6301 6302 6303 6304 6305 6306
sed 's/6379/6301/g' /home/admin/redis/redis.conf > /home/admin/redis/6301/redis.conf
sed 's/6379/6302/g' /home/admin/redis/redis.conf > /home/admin/redis/6302/redis.conf
sed 's/6379/6303/g' /home/admin/redis/redis.conf > /home/admin/redis/6303/redis.conf
sed 's/6379/6304/g' /home/admin/redis/redis.conf > /home/admin/redis/6304/redis.conf
sed 's/6379/6305/g' /home/admin/redis/redis.conf > /home/admin/redis/6305/redis.conf
sed 's/6379/6306/g' /home/admin/redis/redis.conf > /home/admin/redis/6306/redis.conf
redis-server ./6301/redis.conf
redis-server ./6302/redis.conf
redis-server ./6303/redis.conf
redis-server ./6304/redis.conf
redis-server ./6305/redis.conf
redis-server ./6306/redis.conf
然后执行 ps -ef|grep redis,查看下 Redis 启动情况。可以看到我们需要的6个redis实例都已经启动起来,并绑定到指定端口。
集群操作
集群搭建
Redis Cluster 相关命令都可以使用“redis-cli --cluster help”进行查询。
我们现在来使用 Redis Cluster 命令搭建下 Redis 集群,执行命令“redis-cli --cluster create 127.0.0.1:6301 127.0.0.1:6302 127.0.0.1:6303 127.0.0.1:6304 127.0.0.1:6305 127.0.0.1:6306 --cluster-replicas 1”,cluster-replicas 参数是指主/从的比例。
执行命令后可以观察控制台,Redis 会引导我们方便的搭建出集群。为各个节点分好了主/从身份,并且将 slots 槽分散到各个节点。在输入 yes 后将真正搭建 Redis 集群。
可以看到会发送 CLUSTER MEET 消息来加入集群,加入集群后,执行集群节点的检查工作。之后会执行 slots 的open 、 coverage 检查,这些都做完之后集群就正式建立,并可以对外提供服务。
我们执行“redis-cli -p 6301”来连接 6301 这个节点。然后执行 CLUSTER NODES 观察下集群中节点的状态。
可以看到当前连接的节点会有 myself 标识。每个节点分配了节点id,0-5460 表示分配了0-5460 号 slots 槽位。
集群扩容
集群的扩容过程其实也很简单,主分为两步:
- 为集群加入新节点
- 为新节点分配 slots 槽位。
首先我们参照上文的方式再启动两个 redis 实例。
mkdir 6307 6308
sed 's/6379/6307/g' /home/admin/redis/redis.conf > /home/admin/redis/6307/redis.conf
sed 's/6379/6308/g' /home/admin/redis/redis.conf > /home/admin/redis/6308/redis.conf
redis-server ./6307/redis.conf
redis-server ./6308/redis.conf
执行 “ps -ef|grep redis” 命令观察实例是否正常启动。
可以看到 6307、6308 实例已经正常启动。
然后我们执行命令“redis-cli --cluster add-node 127.0.0.1:6307 127.0.0.1:6301”,将 6370 节点加入到已有的集群中。
可以看到还是先执行了集群及 slots 的检查工作,然后发送了 CLUSTER MEET 命令,让 6307 节点加入到集群中。
然后我们连接 6307 节点,并查看下现在的集群状态。
可以看到 6307 节点已经正常的加入到了集群中,并且是 master 节点。
接着我们需要为 6307 节点添加 slave 节点,毕竟单节点是很不安全的。执行命令“redis-cli --cluster add-node 127.0.0.1:6308 127.0.0.1:6301 --cluster-slave --cluster-master-id cfd3daab15f554f7939c2dd7b9e586c21b3c44d6” 即可为指定的节点添加 slave 节点。
可以看到跟添加 6307 节点类似的过程,只不过多了 “Configure node as replica of 127.0.0.1:6307”过程,这个就是为 6307 添加 slave 的指令。
我们再运行 CLUSTER NODES 命令来观察下集群状态。
可以看到 6308 节点已经正常加入集群,并成为了 6307 节点的 slave。
接下来我们需要移动一些 slots 给新加入的节点,毕竟 Redis Cluster 是依赖 slots 来存储、管理数据的,没有 slots 的节点可以算的上是无效节点。
我们执行命令“redis-cli --cluster reshard 127.0.0.1:6301 --cluster-from 4d4c6db51fe4a3c81f055f84acc581e4c5596ee2 --cluster-to cfd3daab15f554f7939c2dd7b9e586c21b3c44d6 --cluster-slots 500”,这个命令也很明了,就是从 6301 节点移动 500 个 slots 到 6307 节点。
Redis 会告知我们移动了哪些 slots ,在输入 yes 后会实际执行移动操作。然后我们再执行“CLUSTER NODES” 名称,来观察下 slots 的移动情况。
可以看到 slots 移动已经生效,6307 节点现在有 0-499 slots,而6301 节点从开始的0-5460 slots 变成了 500-5460 slots。
reshad 命令也提供了一步步的交互方式来移动 slots,例如我们执行命令“redis-cli --cluster reshard 127.0.0.1:6301”。
可以看到 redis 客户端会做如下询问:
- 需要移动多少个 slots
- 哪个节点来接收这些 slots
- 从哪些节点移动 slots (输入all时候会从所有节点进行移动,或者输入节点的id,已done结束)。
在移动完之后我们再通过 “CLUSTER NODES” 命令观察下集群状态。
会发现 slots 的移动完全符合我们的预期。
集群缩容
集群缩容使用“del-node”命令,需要缩容的节点上没有 slots 才可以。比如我们执行如下命令“redis-cli --cluster del-node 127.0.0.1:6301 cfd3daab15f554f7939c2dd7b9e586c21b3c44d6”。
会提示 6307 节点是非空节点,需要 reshard 掉节点上的数据。
在使用上文中 reshard 命令,reshard 掉 6307 节点上的 slots 之后,再执行命令
redis-cli --cluster del-node 127.0.0.1:6301 b6e47ce43a5a0e068da4302bcceba07bc3a60fa8
redis-cli --cluster del-node 127.0.0.1:6301 cfd3daab15f554f7939c2dd7b9e586c21b3c44d6
可以看到都正常发送了 CLUSTER RESET SOFT 命令来删除节点。
集群故障转移
构建 master/slave 结构最大原因是为了防止单点故障,我们来使用 “kill -9” 来杀掉一个实例的进程,观察下redis 的处理过程。
接着通过 "CLUSTER NODES" 命令观察集群状态,可以发现 6307 节点虽然还 master 但已经被标记 fail 状态,而 6308 节点也按照我们预想的变成了 master 节点。
接着我们通过 “redis-server ./6307/redis.conf ” 重新启动 6307 节点,继续观察集群的状态。
可以发现 6307 节点又正常加入到集群中,但是状态也由 master 变成了 slave。Redis 的故障转移机制也完全符合预期。