Docker部署Redis集群
通过Docker搭建Redis集群
一、系统环境
- Redis version :6.0.6
- Docker version 19.03.12 ;
- CentOS Linux release 7.7 ;
二、Redis 集群间通信机制
在 Redis 集群中,数据节点提供两个 TCP 端口,在配置防火墙时需要同时开启下面两类端口:
- 普通端口: 即客户端访问端口,如默认的 6379;
- 集群端口: 普通端口号加 10000,如 6379 的集群端口为 16379,用于集群节点之间的通讯;
集群的节点之间通讯采用 Gossip 协议,节点根据固定频率(每秒10次)定时任务进行判断,当集群状态发生变化,如增删节点、槽状态变更时,会通过节点间通讯同步集群状态,使集群收敛。集群间发送的 Gossip 消息有下面五种消息类型:
- MEET: 在节点握手阶段,对新加入的节点发送 meet 消息,请求新节点加入当前集群,新节点收到消息会回复 pong 消息;
- PING: 节点之间互相发送 ping 消息,收到消息的会回复 pong 消息。ping 消息内容包含本节点和其他节点的状态信息,以此达到状态同步;
- PONG: pong 消息包含自身的状态数据,在接收到 ping 或 meet 消息时会回复 pong 消息,也会主动向集群广播 pong 消息;
- FAIL: 当一个主节点判断另一个主节点进入 fail 状态时,会向集群广播这个消息,接收到的节点会保存该消息并对该 fail 节点做状态判断;
- PUBLISH: 当节点收到 publish 命令时,会先执行命令,然后向集群广播 publish 消息,接收到消息的节点也会执行 publish 命令;
三、Redis 集群失败状态
在 Redis 集群模式下也不可能百分百保证集群可用性,当发生不可预知的事件导致 Redis 集群将进入失败状态,在这种状态下 Redis 集群将不能正常提供服务。其中进入失败状态的条件主要为:
- 全部节点都宕机,集群将进入 fail 状态
- 半数以上主节点不可用,集群将进入 fail 状态;
- 半数以上主节点不可用,集群将进入 fail 状态;
四、Redis 集群重新分片机制
Redis 集群重新分片(新增/移除节点)机制:
- 新增节点:别的节点上的槽分一些出来给新的节点
- 删除节点:删除节点的槽分给别的节点
但这些操作是需要手动完成的,可以在不停止服务器的情况下执行。
五、Redis 集群的不足
- 复制结构只支持单层结构,不支持树型结构。
- 不支持多数据库,只能使用 0 数据库,执行 select 0 命令;
- 键是数据分区的最小粒度,不能将一个很大的键值对映射到不同的节点;
- 键事务支持有限,当多个键分布在不同节点时无法使用事务,同一节点才能支持事务;
- 键的批量操作支持有限,比如 mset, mget 命令,如果多个键映射在不同的槽中,就不能正常使用这些命令了;
六、Redis 群集配置参数
我们即将创建一个示例集群部署。在继续之前,让我们介绍Redis Cluster在redis.conf文件中引入的配置参数。
- cluster-config-file: 设置 Redis 集群配置信息及状态的存储位置,该文件由 Redis 集群生成,我们只能指定其存储的位置。
- cluster-node-timeout: 设置 Redis 群集节点的通信的超时时间;
- cluster-migration-barrier: 主节点需要的最小从节点数,只有达到这个数,主节点失败时,它从节点才会进行迁移。
- cluster-enabled: 是否开启 Redis 集群模式。
- yes:启用 Redis 群集;
- no:不启用集群模式;
- cluster-require-full-coverage: 设置集群可用性。
- yes:表示当负责一个插槽的主库下线,且没有相应的从库进行故障恢复时,集群不可用,下面论证该情况。
- no:表示当负责一个插槽的主库下线且没有相应的从库进行故障恢复时,集群仍然可用,下面论证该情况。
- cluster-slave-validity-factor:
- 0:则无论从节点与主节点失联多久,从节点都会尝试升级成主节点。
- 正数:则 cluster-node-timeout * cluster-slave-validity-factor 得到的时间,是从节点与主节点失联后,此从节点数据有效的最长时间,超过这个时间,从节点不会启动故障迁移。假设 cluster-node-timeout=5,cluster-slave-validity-factor=10,则如果从节点跟主节点失联超过50秒,此从节点不能成为主节点。
七、Docker 部署 Redis 集群
1、Redis 部署机器分配
服务器IP | 端口 | 数据存储位置 |
---|---|---|
192.168.0.71 | -7000 | -/var/lib/redis/7000 |
192.168.0.71 | -7003 | -/var/lib/redis/7003 |
192.168.0.72 | -7001 | -/var/lib/redis/7001 |
192.168.0.72 | -7004 | -/var/lib/redis/7004 |
192.168.0.73 | -7002 | -/var/lib/redis/7002 |
192.168.0.73 | -7005 | -/var/lib/redis/7005 |
2、创建数据存储目录
提前创建好用于存储 Redis 的配置文件和持久化数据的目录:
第一台服务器 192.168.0.71 中执行创建存储目录命令:
mkdir -p /var/lib/redis/7000 & mkdir -p /var/lib/redis/7003
第二台服务器 192.168.0.72 中执行创建存储目录命令:
mkdir -p /var/lib/redis/7001 & mkdir -p /var/lib/redis/7004
第三台服务器 192.168.0.73 中执行创建存储目录命令:
mkdir -p /var/lib/redis/7002 & mkdir -p /var/lib/redis/7005
3、创建 Redis 配置文件
第一台服务器 192.168.0.71 配置文件:
## 7000 端口配置文件
$ cat > /var/lib/redis/7000/redis.conf << EOF
port 7000
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize no
protected-mode no
pidfile /data/redis.pid
EOF
## 7003 端口配置文件
$ cat > /var/lib/redis/7003/redis.conf << EOF
port 7003
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize no
protected-mode no
pidfile /data/redis.pid
EOF
第二台服务器 192.168.0.72 配置文件:
## 7001 端口配置:redis.conf
$ cat > /var/lib/redis/7001/redis.conf << EOF
port 7001
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize no
protected-mode no
pidfile /data/redis.pid
EOF
## 7004 端口配置:redis-7004.conf
$ cat > /var/lib/redis/7004/redis.conf << EOF
port 7004
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize no
protected-mode no
pidfile /data/redis.pid
EOF
第三台服务器 192.168.0.73 配置文件
## 7002 端口配置:redis-7002.conf
$ cat > /var/lib/redis/7002/redis.conf << EOF
port 7002
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize no
protected-mode no
pidfile /data/redis.pid
EOF
## 7005 端口配置:redis-7005.conf
$ cat > /var/lib/redis/7005/redis.conf << EOF
port 7005
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
appendonly yes
daemonize no
protected-mode no
pidfile /data/redis.pid
EOF
4、创建执行docker脚本
可以提前执行拉取redis镜像
docker pull redis:6.0.8
-
第一台服务器 192.168.0.71 执行脚本
redis7000.sh
#! /bin/bash docker stop redis-7000 docker rm redis-7000 docker run -d -v /var/lib/redis/7000:/data \ --cpus=1 --memory=2GB --memory-swap=0 \ --privileged=true \ --restart=always \ --net host \ --name redis-7000 \ redis:6.0.8 redis-server /data/redis.conf
redis7003.sh
#! /bin/bash docker stop redis-7003 docker rm redis-7003 docker run -d -v /var/lib/redis/7003:/data \ --cpus=1 --memory=2GB --memory-swap=0 \ --privileged=true \ --restart=always \ --net host \ --name redis-7003 \ redis:6.0.8 redis-server /data/redis.conf
-
第一台服务器 192.168.0.72 执行脚本
redis7001.sh#! /bin/bash docker stop redis-7001 docker rm redis-7001 docker run -d -v /var/lib/redis/7001:/data \ --cpus=1 --memory=2GB --memory-swap=0 \ --privileged=true \ --restart=always \ --net host \ --name redis-7001 \ redis:6.0.8 redis-server /data/redis.conf
redis7004.sh
#! /bin/bash docker stop redis-7004 docker rm redis-7004 docker run -d -v /var/lib/redis/7004:/data \ --cpus=1 --memory=2GB --memory-swap=0 \ --privileged=true \ --restart=always \ --net host \ --name redis-7004 \ redis:6.0.8 redis-server /data/redis.conf
-
第一台服务器 192.168.0.73 执行脚本
redis7002.sh#! /bin/bash docker stop redis-7002 docker rm redis-7002 docker run -d -v /var/lib/redis/7002:/data \ --cpus=1 --memory=2GB --memory-swap=0 \ --privileged=true \ --restart=always \ --net host \ --name redis-7002 \ redis:6.0.8 redis-server /data/redis.conf
redis7005.sh
#! /bin/bash docker stop redis-7005 docker rm redis-7005 docker run -d -v /var/lib/redis/7005:/data \ --cpus=1 --memory=2GB --memory-swap=0 \ --privileged=true \ --restart=always \ --net host \ --name redis-7005 \ redis:6.0.8 redis-server /data/redis.conf
参数介绍
- -d:设置容器后台运行;
- –name:指定运行后的容器名称;
- –cpus:指定容器使用 CPU 数量;
- –memory:限制容器使用内存数量;
- –memory-swap:指定交换内存大小,这里设置为 0,即不用交换内存;
- –net:指定 Docker 使用的网络模式;
- -restart:指定 Docker 重启时容器的重启策略;
- –privileged:设置容器拥有特权,能够获取宿主机 Root 权限;
查看启动端口信息:
docker logs redis-7002
##
docker logs redis-7005
5、创建redis集群
随意进入一台服务器,使用 Redis 镜像的 redis-cli 工具执行创建集群命令使各个 Redis 组成集群,这里本人进入第一台服务器 192.168.0.71 中,使用端口为 7000 的 Redis 端镜像,可以执行下面命令:
- -p:指定连接 Redis 的端口;
- create:创建 Redis 集群;
- –cluster:使用 Redis 集群模式命令;
- –cluster-replicas:指定副本数(slave 数量);
docker exec -it redis-7000 \
redis-cli -p 7000 --cluster create \
192.168.0.71:7000 192.168.0.72:7001 192.168.0.73:7002 \
192.168.0.71:7003 192.168.0.72:7004 192.168.0.73:7005 \
--cluster-replicas 1
执行后会看到以下信息
6、查看集群信息
进入 Redis 镜像内部并折佣 redis-cli 命令:
- -p:指定连接 Redis 的端点;
- -c:使用集群模式;
我这里连接的是第二台机器(随意那台)
docker exec it redis-7001 redis-cli -p 7001 -c
查看集群信息:
查看集群节点信息:
7、集群连接使用测试