docker搭建redis三种集群模式
一、主从复制
这儿采用docker进行安装redis,比较简单不过多解释了。
# 这儿安装的是7.0.5版本,也是最此时的新版
docker pull redis:7.0.5
#也可直接使用
docker pull redis
1、新建修改配置文件
在/user/local目录下新建文件夹,并在此文件夹下建了三个文件对应一主二从。
cd /user/local
mkdir redis_replication
cd redis_replication
mkdir master
mkdir slave01
mkdir slave02
修改redis.conf配置文件
主节点 配置文件
1、修改bind或注释掉
bind 0.0.0.0
2、保护模式关闭,因为用docker否则无法访问
protected-mode no
3、设置密码
requirepass 设置密码
4、开启aof日志
appendonly yes
从节点 配置文件
在上述的主节点配置的基础上
1、修改自己的端口号(二从的端口号不要相同)
port 6380和6381
2、配置与主节点验证的密码
masterauth 设置密码
3、配置主节点的ip端口,认证主节点主从复制
replicaof 主机IP 主机端口
注意:
- 主节点与从节点的密码要保持一致,方便后面的
哨兵模式。 -
daemonize这个配置设置为no,因为要用docker -d命令,这两个有冲突,若不用docker的话可以开启。
将配置文件分别复制到一主二从的conf文件夹下。
2、执行命令启动redis
# 主节点
docker run -d --privileged=true -v /usr/local/redis_replication/master/data:/data -v /usr/local/redis_replication/master/conf:/etc/redis -p 6379:6379 --name redis_master redis:7.0 redis-server /etc/redis/redis.conf
# 从节点01
docker run -d --privileged=true -v /usr/local/redis_replication/slave01/data:/data -v /usr/local/redis_replication/slave01/conf:/etc/redis -p 6380:6380 --name redis_slave01 redis:7.0 redis-server /etc/redis/redis.conf
# 从节点02
docker run -d --privileged=true -v /usr/local/redis_replication/slave02/data:/data -v /usr/local/redis_replication/slave02/conf:/etc/redis -p 6381:6381 --name redis_slave02 redis:7.0 redis-server /etc/redis/redis.conf
若出现报错
docker logs tail 200 容器id或名称
3、启动客户端测试
进入主从docker容器内:
docker exec -it 容器ID或名称 /bin/bash
# 运行客户端
redic_cli -p 6379 -a 密码
# 查看信息
info replication
# 展示如下信息
# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=1843834,lag=0
slave1:ip=127.0.0.1,port=6381,state=online,offset=1843414,lag=0
master_failover_state:no-failover
master_replid:9fc3d09efced8e02a2b9204358ad53d94a25de1a
master_replid2:99c68add0e6fa1f508ed43b2dce3f0348672ae5b
master_repl_offset:1843834
second_repl_offset:7845
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:782860
repl_backlog_histlen:1060975
在主节点 set k v,在从节点查看是否同步成功 get k
二、哨兵模式Sentinel
哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵通过发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。
主要两步:
- 启动
redis主从复制(前面已经启动了)。 - 配置
sentinel并启动。
1、修改配置文件
sentinel.conf配置文件
# 修改端口不要重复,这儿26379 26380 26381
port 26379
# 设置日志存储位置
logfile "/data/sentinel.log"
# 监控主节点的配置 mymaster名字随便起;2因为是三台哨兵,所以大于等于半数票数2
sentinel monitor mymaster 主节点IP 主节点端口 2
# 配置主节点密码
sentinel auth-pass mymaster 密码
修改主节点的redis.conf配置文件,因为主节点也可能成为从节点。
所以前面要保持主从密码一致。
masterauth 设置密码
将配置文件分别复制到一主二从的conf文件夹下。
注意: 配置密码时候看清是auth-pass,笔者错配成了auth-user耽误了并不少时间
2、启动sentinel进程
# 主节点sentinel
docker run -itd --privileged=true -v /usr/local/redis_replication/master/data:/data -v /usr/local/redis_replication/master/conf:/etc/redis -p 26379:26379 --name redis_sentinel redis:7.0 redis-sentinel /etc/redis/sentinel.conf
# 从节点01 sentinel
docker run -itd --privileged=true -v /usr/local/redis_replication/slave01/data:/data -v /usr/local/redis_replication/slave01/conf:/etc/redis -p 26380:26380 --name redis_sentinel01 redis:7.0 redis-sentinel /etc/redis/sentinel.conf
# 从节点02 sentinel
docker run -itd --privileged=true -v /usr/local/redis_replication/slave02/data:/data -v /usr/local/redis_replication/slave02/conf:/etc/redis -p 26381:26381 --name redis_sentinel02 redis:7.0 redis-sentinel /etc/redis/sentinel.conf
进入sentinel
docker exec -it redis_sentinel /bin/bash
# 运行客户端
redic_cli -p 26379
# 查看信息
info sentinel
# 展示如下信息
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_tilt_since_seconds:-1
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=127.0.0.1x:6379,slaves=2,sentinels=3
3、测试
- 关闭
master节点
docker stop redis_master
- 观察
sentinel.log信息
这儿有完整的从节点上位的过程
1:X 13 Dec 2022 02:54:17.611 # User requested shutdown...
1:X 13 Dec 2022 02:54:17.611 * Removing the pid file.
1:X 13 Dec 2022 02:54:17.611 # Sentinel is now ready to exit, bye bye...
1:X 13 Dec 2022 02:54:18.175 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
1:X 13 Dec 2022 02:54:18.175 # Redis version=7.0.5, bits=64, commit=00000000, modified=0, pid=1, just started
1:X 13 Dec 2022 02:54:18.175 # Configuration loaded
1:X 13 Dec 2022 02:54:18.175 * monotonic clock: POSIX clock_gettime
1:X 13 Dec 2022 02:54:18.177 * Running mode=sentinel, port=26379.
1:X 13 Dec 2022 02:54:18.177 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
1:X 13 Dec 2022 02:54:18.178 # Sentinel ID is 0489f75140810f172f63af196e845bd8584e520e
1:X 13 Dec 2022 02:54:18.178 # +monitor master mymaster 127.0.0.1 6379 quorum 2
1:X 13 Dec 2022 02:54:44.805 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
1:X 13 Dec 2022 02:54:44.810 * Sentinel new configuration saved on disk
1:X 13 Dec 2022 02:54:44.810 * +convert-to-slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6379
1:X 13 Dec 2022 02:55:35.521 * Sentinel new configuration saved on disk
1:X 13 Dec 2022 02:55:35.521 # +new-epoch 21
1:X 13 Dec 2022 02:55:35.524 * Sentinel new configuration saved on disk
1:X 13 Dec 2022 02:55:35.525 # +vote-for-leader ed60d0f591b217fe3361a019b9dd6398f3b1d833 21
1:X 13 Dec 2022 02:55:35.931 # +config-update-from sentinel ed60d0f591b217fe3361a019b9dd6398f3b1d833 172.17.0.8 26380 @ mymaster 127.0.0.1 6379
1:X 13 Dec 2022 02:55:35.931 # +switch-master mymaster 127.0.0.1 6379 127.0.0.1 6381
1:X 13 Dec 2022 02:55:35.931 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6381
1:X 13 Dec 2022 02:55:35.931 * +slave slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381
1:X 13 Dec 2022 02:55:35.939 * Sentinel new configuration saved on disk
1:X 13 Dec 2022 02:56:05.973 # +sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381
1:X 13 Dec 2022 02:57:07.229 # -sdown slave 127.0.0.1:6379 127.0.0.1 6379 @ mymaster 127.0.0.1 6381
- 查看
6381端口的信息,发现成功上位成主节点。 - 重启
6379节点,发现该节点变成了从节点。
注意: 若重新启动sentinel记得修改配置文件监控为主节点。
sentinel monitor mymaster 主节点IP 主节点端口 2
三、集群模式Cluster
1、搭建集群
1.1、创建集群挂载文件
在 /usr/local/redis_cluster 文件夹下 创建8个文件
mkdir master01
mkdir master02
mkdir master03
mkdir master04
mkdir slave01
mkdir slave02
mkdir slave03
mkdir slave04
并在对应的目录下创建conf文件,把redis.conf复制进conf文件夹下。
1.2、修改配置文件
新建八个配置文件依次放入conf文件夹下。
1、修改端口号,八个文件端口不要重复
port 6382
2、修改bind或注释掉
bind 0.0.0.0
3、保护模式关闭,因为用docker否则无法访问
protected-mode no
4、关闭后台运行
daemonize no
5、设置密码
requirepass 设置密码
6、配置与主节点验证的密码
masterauth 设置密码
7、开启aof日志
appendonly yes
8、开启集群模式
cluster-enabled yes
9、根据你启用的节点来命名,最好和端口保持一致,这个是用来保存其他节点的名称,状态等信息的
cluster-config-file nodes_6379.conf
10、超时时间
cluster-node-timeout 5000
11、集群节点 IP:服务器就填公网ip,或者内部对应容器的ip
cluster-announce-ip xx.xxx.xxx.xx
12、集群节点映射端口
cluster-announce-port 6382
13、总线监控ip默认端口+10000 如 6382 就是 16382
cluster-announce-bus-port 16382
1.3、docker 容器网络
- 创建虚拟网卡?
docker network create redis_cluster
- 查看Docker 网卡信息
docker network ls
- 查看dockerr网络详细信息
docker network inspect redis_cluster
- 补充(删除网卡信息、帮助命令)
docker network rm redis_cluster #删除网卡命令 多个中间 空格隔开
docker network --help #显示可带参数等
1.4、docker启动先六个redis实例
docker run -d --privileged=true -v /usr/local/redis_cluster/master01/data:/data -v /usr/local/redis_cluster/master01/conf:/etc/redis -p 6382:6382 -p 16382:16382 --name redis_cluster6382 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/master02/data:/data -v /usr/local/redis_cluster/master02/conf:/etc/redis -p 6383:6383 -p 16383:16383 --name redis_cluster6383 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/master03/data:/data -v /usr/local/redis_cluster/master03/conf:/etc/redis -p 6384:6384 -p 16384:16384 --name redis_cluster6384 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/slave01/data:/data -v /usr/local/redis_cluster/slave01/conf:/etc/redis -p 6385:6385 -p 16385:16385 --name redis_cluster6385 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/slave02/data:/data -v /usr/local/redis_cluster/slave02/conf:/etc/redis -p 6386:6386 -p 16386:16386 --name redis_cluster6386 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/slave03/data:/data -v /usr/local/redis_cluster/slave03/conf:/etc/redis -p 6387:6387 -p 16387:16387 --name redis_cluster6387 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
1.5、构建集群
redis-cli -a 密码 --cluster create xx.xxx.xx.xxx:6382 xx.xxx.xx.xxx:6383 xx.xxx.xx.xxx:6384 xx.xxx.xx.xxx:6385 xx.xxx.xx.xxx:6386 xx.xxx.xx.xxx:6387 --cluster-replicas 1
--cluster-replicas 1 :为每一个主节点创建一个副本所以这儿 3主3从
展示如下信息

1.5、查看集群状态
# 查看集群状态以及节点关系
redis-cli -p 6382 -a 密码 --cluster check xx.xxx.xx.xxx 6382
# 进入redis-cli
redis-cli -p 6382 -a 密码 -c
# 查看cluster信息
cluster info
# 查看节点信息
cluster nodes
2、容错测试
2.1、数据存储
# 当设置不属于当前节点的槽位的key value时,发现会重定向到另一个槽位节点
set k1 v1
-> Redirected to slot [12706] located at xx.xxx.xx.xxx:6384
OK
2.2、关闭master节点,容错机制
- 停止6384主节点,观察从节点是否上位
docker stop redis_cluster6384
- 查看节点状态
redis-cli -p 6382 -a 密码 --cluster check xx.xxx.xx.xxx 6382
这儿就不再截图啦,会发现6387节点上位,成为主节点
- 还原集群状态为原始状态
3、节点扩容
3.1、启动6388,6389节点
docker run -d --privileged=true -v /usr/local/redis_cluster/master04/data:/data -v /usr/local/redis_cluster/master04/conf:/etc/redis -p 6388:6388 -p 16388:16388 --name redis_cluster6388 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
docker run -d --privileged=true -v /usr/local/redis_cluster/slave04/data:/data -v /usr/local/redis_cluster/slave04/conf:/etc/redis -p 6389:6389 -p 16389:16389 --name redis_cluster6389 --net redis_cluster redis:7.0 redis-server /etc/redis/redis.conf
3.2、加入集群
- 6388节点加入集群
# 添加节点到集群
redis-cli -a 密码 --cluster add-node xx.xxx.xx.xxx:6388 xx.xxx.xx.xxx:6382
- 6389节点加入集群并绑定6388主节点
# 绑定从节点与主节点
redis-cli -a 密码 --cluster add-node xx.xxx.xx.xxx:6389 xx.xxx.xx.xxx:6388 --cluster-slave --cluster-master-id 204fbd5f8e9d71a865c75f34f4d48121e9d4cff2
--cluster-slave : 作为从节点。
--cluster-master-id: 指定关联的主节点,后面跟上 主节点 ID。
- 观察节点状态
redis-cli -p 6382 -a 密码 --cluster check xx.xxx.xx.xxx 6382
# 展示如下
xx.xxx.xx.xxx:6382 (33b306d8...) -> 2 keys | 5461 slots | 1 slaves.-id 2a7494a93e
xx.xxx.xx.xxx:6383 (9a01058a...) -> 0 keys | 5462 slots | 1 slaves.
xx.xxx.xx.xxx:6384 (bb3b2354...) -> 1 keys | 5461 slots | 1 slaves.
xx.xxx.xx.xxx:6388 (2a7494a9...) -> 0 keys | 0 slots | 0 slaves.
还未对6388节点分配槽位。
3.2、分配槽位
redis-cli -a 密码 --cluster reshard xx.xxx.xx.xxx:6382
- How many slots do you want to move (from 1 to 16384)?
这儿是说要分配给目标多少槽位 ? 4096 (16384/4=4096)
- What is the receiving node ID?
分配给谁? 这儿填6388槽位的ID,2a7494a93ef14f755d2494afaefc4d91aae21f00
- Type ‘all’ to use all the nodes as source nodes for the hash slots.
Type ‘done’ once you entered all the source nodes IDs.
all :其他的所有节点的槽位会均匀分给6388节点
done:指定节点的槽位分给6388,需要先指定节点id,最后使用done
这儿选all 均匀分配。
-
后面直接
yes。 -
在此检查集群状态。观察6388已经有4096个槽位了,并且取自另三个主节点。
4、节点缩容
将 6388和6389节点下线。
4.1、下线6389从节点
redis-cli -a 密码 --cluster del-node xx.xxx.xx.xxx:6382 204fbd5f8e9d71a865c75f34f4d48121e9d4cff2
后面是6389的 ID。
- 检查集群状态
4.2、分配6388节点的槽位
redis-cli -a 密码 --cluster reshard xx.xxx.xx.xxx:6382
这儿原ID为6388的ID,接收者为6382的ID,然后done。意思是将所有的槽位分配给6382。
- 检查集群状态
4.3、删除6388节点
redis-cli -a 密码 --cluster del-node xx.xxx.xx.xxx:6382 2a7494a93ef14f755d2494afaefc4d91aae21f00
- 检查集群状态
4.5、关闭 6388和6389节点
docker stop redis_cluster6388 redis_cluster6389
5、命令总结
# 查看节点关系
redis-cli -p 6382 -a 密码 --cluster check xx.xxx.xx.xxx 6382
# 进入redis-cli
cluster info
cluster nodes
# 添加节点到集群
redis-cli -a 密码 --cluster add-node xx.xxx.xx.xxx:6388 xx.xxx.xx.xxx:6382
# 绑定从节点与主节点
redis-cli -a 密码 --cluster add-node xx.xxx.xx.xxx:6389 xx.xxx.xx.xxx:6388 --cluster-slave --cluster-master-id 2a7494a93ef14f755d2494afaefc4d91aae21f00
# 重新洗牌 槽位
redis-cli -a 密码 --cluster reshard xx.xxx.xx.xxx:6382
# 修复
redis-cli -a 密码 --cluster fix xx.xxx.xx.xxx:6382 --cluster-search-multiple-owners --cluster-fix-with-unreachable-masters
## 删除节点
redis-cli -a 密码 --cluster del-node xx.xxx.xx.xxx:6388 14cdb77543100a21791797a68a8e23229efe8c23
四、遇到的问题
1、集群搭建过程时,一直卡在 Waiting for the cluster to join 这儿不动。
原因就是网络造成的。
1、使用docker时候记得加 --net xxxx 网络虚拟组进行链接。
2、若使用云服务器,如阿里云记得防火墙开放对应的端口,记得开放redis总线端口,默认是端口号+10000。
3、我这儿是直接自己指定IP端口 cluster-announce-ip,没有使用默认的规则。