Docker基础知识 (16) - 使用 Docker 部署 Redis 集群
Redis 是一个开源的使用 ANSI C 语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value 的 NoSQL 数据库,并提供多种语言的 API。
大型网站为了提高站点响应速度,使用缓存工具将热点数据保存在内存中,避免直接从后端数据库读取查询,降低后端压力,其中常见的 Cache 工具有 Memcached 和 Redis。
Memcached 更侧重于⾼性能内存/缓存系统,⽽ Redis 则⽀持持久化,主打数据库功能,兼可作缓存系统(性能也很⾼)。如果业务中更加侧重性能的⾼效性,对持久化要求不⾼,那么应该优先选择 Memcached。如果业务中对持久化有需求或者对数据涉及到存储、排序等一系列复杂的操作,比如业务中有排⾏榜类应⽤、社交关系存储、数据排重、实时配置等功能,那么应该优先选择 Redis。
在大型站点应用中,热点数据几十 ~ 上百 G 很普遍,而无论是物理机、云主机(虚拟机),内存资源往往是有限的,虽然目前硬件成本降低,几十 G 几十核的主机也很常见,但是对于 Redis 这种工作进程为单线程模式的工具来说,一台主机只运行一个实例就有些浪费,且出现单点故障时影响范围很大。同时,Redis 管理大内存时不如管理相对较小的内存高效,据第三方测试,Redis 单进程内存分配达到 20G 后性能急剧下降,因此普遍使用的方式为单进程分配 8G 内存,单主机开启多个 Redis Instance.
Redis 三种集群方式:主从复制、哨兵模式(Sentinel)、Cluster 集群。
主从复制:
从服务器将向主服务器发送 SYNC 命令,接收到 SYNC 命令后的主服务器会进行一次 BGSAVE 命令,在执行期间,会将所有命令写入缓冲区中,当 BGSAVE 命令执行完毕之后会将生成的 RDB 文件发送给从服务器,从服务器使用这个文件加载数据到内存中,之后主服务器会以 Redis 命令协议的格式将缓冲区的命令发送给从服务器。
此后每次主服务执行命令都会同步给从服务器,即使有多个从服务器向主服务器发送 SYNC 命令,主服务器也只会执行一个 BGSAVE 命令,就可以处理接下来的同步请求。一个主服务器可以拥有多个从服务器,而从服务器也可拥有从服务器,复制功能不会阻塞主服务器,即使有一个或多个同步请求,主服务器依然能处理命令请求。
当配置了主从复制模式时需要开启主服务器的持久化功能,如果将主服务器的持久化功能关闭,主服务器一旦重启,所有从服务器的数据将会丢失,即使配置了 Sentinel 模式,如果主服务器自动拉起进程比较快,以至于在 Sentinel 模式下还未选举出新的主服务器,主服务的启动也会造成子服务器的数据丢失。
哨兵模式:
Redis 的 Sentinel 系统用于管理多个 Redis,主要执行以下三件事:
(1) 监控:Sentinel 会不断的检查主从服务器运行状态;
(2) 提醒:当某个 Redis 服务器出现故障,可通过 API 或者其他应用程序发送通知;
(3) 自动故障迁移:当一个主服务器不能正常工作时,Sentinel 会进行一次故障自动迁移,会将失效主服务器的从服务器选举出一个新的主服务器,剩下的从服务器将会自动连接复制选举出来的新服务器的数据;
Redis 的 Sentinel 系统是一个分布式的系统,可以在系统中配置一个或多个 Sentinel。
当一个 Sentinel 发现主服务器下线时,称为主观下线,只有多个 Sentinel 都发现主服务下线,并相互之间通过命令进行交流判断主服务器下线时,称为客观下线。只有对主服务器进行客观下线时,会选举出领头 Sentinel,选举出之后,会进行新的主服务器投票选举,选举出一个从服务器升级为主服务器。并向被选中的从服务器发送 SLAVEOF no one 命令,让其变为主服务器,通过发布订阅的功能,将新的配置广播给其他 Sentinel 进行更新,并向下线的主服务器发送 SLAVEOF 命令,让其复制新的主服务器,当所有从服务器都已经开始复制新的主服务器时,领头 Sentinel 终止本次故障迁移。
当一个 Redis 实例被重新配置是,无论是被设置成主服务器、从服务器、又或者被设置成其他主服务器的从服务器 ,Sentinel 都会向被重新配置的实例发送一个 CONFIG REWRITE 命令, 从而确保这些配置会持久化在硬盘里。
Redis cluster:
主从复制和哨兵模式都难以在线扩容,而 Redis cluster 集群实现了对 Redis 的水平扩容,即启动 N 个Redis 节点,每个节点又可以有自己的从服务器,将数据均匀分布的存储在这 N 个结点上,每个节点存储数据的 1/N。Redis cluster 集群就是一个可以在多个 Redis 节点之间进行数据共享的设施;Redis cluster 集群采用的是无中心化配置,即节点 A 无法处理,会将请求转发至节点 B 进行处理。
Redis 集群中的键空间被分割为 16384 个槽位。每个主节点负责 16384 中槽位的一部分,Redis 使用CRC16 算法进行槽位分配。为了保证高可用,cluster 模式也引入了主从复制模式,一个主节点对应一个或多个从节点,当主节点发生宕机时,可进行故障转移,将子节点升级为主节点。
本文部署 3 个 Redis 节点,来演示主从复制和哨兵模式,部署 6 个节点(至少 6 个节点),来演示 Cluster 集群。
1. 部署环境
IP 地址(本地测试环境):192.168.0.10
操作系统:Linux CentOS 7.9
Docker 版本: 20.10.7
Docker Compose 版本: 2.6.1
Redis 集群目录:/home/docker/redis_cluster
2. Redis 集群目录
在 /home/docker/redis_cluster 目录下,目录结构如下:
redis_cluster
|- master
| |- conf
| | |- redis.cnf
| |
| |- data
| |- log
|
|- node_1
| |- conf
| | |- redis.cnf
| |
| |- data
| |- log
|
|- node_2
| |- conf
| | |- redis.cnf
| |
| |- data
| |- log
|
| ...
|
|- scripts
| |- run_redis_server.sh
|
|- replication
| |- docker-compose.yml
|
|- sentinel
| |- conf_1
| | |- sentinel.cnf
| |- conf_2
| | |- sentinel.cnf
| |- conf_3
| | |- sentinel.cnf
| |
| | ...
| |
| |- docker-compose.yml
|
|- cluster
| |- docker-compose.yml
|
|- common.env
3. 配置文件
1) 创建 master 的 redis.conf 文件
在 /home/docker/redis_cluster/master/conf 目录下,创建 redis.conf 文件,内容如下:
bind 0.0.0.0
port 6379
protected-mode no
slave-read-only no
logfile /var/log/redis.log
#dir /data
2) 创建 node_1 的 redis.conf 文件
在 /home/docker/redis_cluster/node_1/conf 目录下,创建 redis.conf 文件,内容如下:
bind 0.0.0.0
port 6380
protected-mode no
slave-read-only no
logfile /var/log/redis.log
#dir /data
3) 创建 node_2 的 redis.conf 文件
在 /home/docker/redis_cluster/node_2/conf 目录下,创建 redis.conf 文件,内容如下:
bind 0.0.0.0
port 6381
protected-mode no
slave-read-only no
logfile /var/log/redis.log
#dir /data
4) 创建 common.env 文件
在 /home/docker/redis_cluster 目录下,创建 common.env 文件,内容如下:
REQUIRE_PASS=123456
MASTER_AUTH=123456
MASTER_HOST=redis_master
MASTER_PORT=6379
5) 创建 run_redis_server.sh 文件
在 /home/docker/redis_cluster/scripts 目录下,创建 run_redis_server.sh 文件,内容如下:
#!/bin/bash
if [[ $1 = 'master' ]]; then
redis-server /etc/redis/redis.conf --requirepass $REQUIRE_PASS --masterauth $MASTER_AUTH
elif [[ $1 = 'slave' ]]; then
redis-server /etc/redis/redis.conf --slaveof $MASTER_HOST $MASTER_PORT --requirepass $REQUIRE_PASS --masterauth $MASTER_AUTH
else
echo "Usage: $0 [master|slave]"
echo " master - Redis master"
echo " slave - Redis slave"
fi
4. 主从复制 (Replication)
1) 创建 docker-compose.yml
在 /home/docker/redis_cluster/replication 目录下,创建 docker-compose.yml 文件,内容如下:
version: "3"
services:
redis_master:
image: redis:6
container_name: redis_master
volumes:
- /home/docker/redis_cluster/master/data:/data
- /home/docker/redis_cluster/master/conf:/etc/redis
- /home/docker/redis_cluster/master/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.10
command: /bin/bash /root/redis_scripts/run_redis_server.sh master
env_file:
- /home/docker/redis_cluster/common.env
redis_node_1:
image: redis:6
container_name: redis_node_1
depends_on:
- redis_master
volumes:
- /home/docker/redis_cluster/node_1/data:/data
- /home/docker/redis_cluster/node_1/conf:/etc/redis
- /home/docker/redis_cluster/node_1/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.11
command: /bin/bash /root/redis_scripts/run_redis_server.sh slave
env_file:
- /home/docker/redis_cluster/common.env
redis_node_2:
image: redis:6
container_name: redis_node_2
depends_on:
- redis_master
volumes:
- /home/docker/redis_cluster/node_2/data:/data
- /home/docker/redis_cluster/node_2/conf:/etc/redis
- /home/docker/redis_cluster/node_2/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.12
command: /bin/bash /root/redis_scripts/run_redis_server.sh slave
env_file:
- /home/docker/redis_cluster/common.env
networks:
my_net:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/16
2) 启动
$ cd /home/docker/redis_cluster/replication
$ docker-compose up -d # 在后台运行
[+] Running 4/4
⠿ Network redis_cluster_my_net Created 0.0s
⠿ Container redis_node_1 Started 0.6s
⠿ Container redis_node_2 Started 0.6s
⠿ Container redis_master Started 0.6s
注:本地 docker 没有所需要的镜像时,会自动下载所需的镜像。遇到无法自动下载的情况,可以使用 docker pull 命令下载所需的镜像,再运行 docker-compose up 命令。
$ docker images # 查看镜像
REPOSITORY TAG IMAGE ID CREATED SIZE
redis 6 136fbb04568e 7 days ago 113MB
$ docker ps
CONTAINER ID IMAGE COMMAND ... PORTS NAMES
06ea72a37b5f redis:6 "docker-entrypoint.s…" 6379/tcp redis_master
e9db204dfced redis:6 "docker-entrypoint.s…" 6379/tcp redis_node_2
d150fd52bf13 redis:6 "docker-entrypoint.s…" 6379/tcp redis_node_1
$ docker exec -it redis_master /bin/bash # 进入 redis_master 容器
root@a762d02ea05f:/data# redis-cli -p 6379
127.0.0.1:6379> auth 123456
OK
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.25.0.11,port=6380,state=online,offset=4858,lag=1
slave1:ip=172.25.0.12,port=6381,state=online,offset=4858,lag=1
master_failover_state:no-failover
master_replid:d5971ebdc023fdbeff153f84b51c047744db6456
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:4858
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:4858
5. 哨兵模式 (Sentinel)
1) 创建 Sentinel 配置文件
在 /home/docker/redis_cluster/sentinel/conf_1 目录下,创建 sentinel.conf 文件,内容如下:
port 26379
dir /tmp
sentinel monitor the_master 172.25.0.10 6379 2
sentinel auth-pass the_master 123456
sentinel down-after-milliseconds the_master 30000
sentinel parallel-syncs the_master 1
sentinel failover-timeout the_master 10000
sentinel deny-scripts-reconfig yes
在 /home/docker/redis_cluster/sentinel/conf_2 目录下,创建 sentinel.conf 文件,内容如下:
port 26380
dir /tmp
sentinel monitor the_master 172.25.0.10 6379 2
sentinel auth-pass the_master 123456
sentinel down-after-milliseconds the_master 30000
sentinel parallel-syncs the_master 1
sentinel failover-timeout the_master 10000
sentinel deny-scripts-reconfig yes
在 /home/docker/redis_cluster/sentinel/conf_3 目录下,创建 sentinel.conf 文件,内容如下:
port 26381
dir /tmp
sentinel monitor the_master 172.25.0.10 6379 2
sentinel auth-pass the_master 123456
sentinel down-after-milliseconds the_master 30000
sentinel parallel-syncs the_master 1
sentinel failover-timeout the_master 10000
sentinel deny-scripts-reconfig yes
2) 创建 docker-compose.yml
在 /home/docker/redis_cluster/sentinel 目录下,创建 docker-compose.yml 文件,内容如下:
version: "3"
services:
redis_master:
image: redis:6
container_name: redis_master
volumes:
- /home/docker/redis_cluster/master/data:/data
- /home/docker/redis_cluster/master/conf:/etc/redis
- /home/docker/redis_cluster/master/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.10
command: /bin/bash /root/redis_scripts/run_redis_server.sh master
env_file:
- /home/docker/redis_cluster/common.env
redis_node_1:
image: redis:6
container_name: redis_node_1
depends_on:
- redis_master
volumes:
- /home/docker/redis_cluster/node_1/data:/data
- /home/docker/redis_cluster/node_1/conf:/etc/redis
- /home/docker/redis_cluster/node_1/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.11
command: /bin/bash /root/redis_scripts/run_redis_server.sh slave
env_file:
- /home/docker/redis_cluster/common.env
redis_node_2:
image: redis:6
container_name: redis_node_2
depends_on:
- redis_master
volumes:
- /home/docker/redis_cluster/node_2/data:/data
- /home/docker/redis_cluster/node_2/conf:/etc/redis
- /home/docker/redis_cluster/node_2/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.12
command: /bin/bash /root/redis_scripts/run_redis_server.sh slave
env_file:
- /home/docker/redis_cluster/common.env
sentinel_1:
image: redis:6
container_name: redis_sentinel_1
depends_on:
- redis_master
- redis_node_1
- redis_node_2
volumes:
- /home/docker/redis_cluster/sentinel/conf_1:/usr/local/etc/redis
networks:
my_net:
ipv4_address: 172.25.0.13
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
sentinel_2:
image: redis:6
container_name: redis_sentinel_2
depends_on:
- redis_master
- redis_node_1
- redis_node_2
volumes:
- /home/docker/redis_cluster/sentinel/conf_2:/usr/local/etc/redis
networks:
my_net:
ipv4_address: 172.25.0.14
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
sentinel_3:
image: redis:6
container_name: redis_sentinel_3
depends_on:
- redis_master
- redis_node_1
- redis_node_2
volumes:
- /home/docker/redis_cluster/sentinel/conf_3:/usr/local/etc/redis
networks:
my_net:
ipv4_address: 172.25.0.15
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
networks:
my_net:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/16
3) 启动
$ cd /home/docker/redis_cluster/sentinel
$ docker-compose up
[+] Running 7/7r sentinel]# docker-compose up
⠿ Network sentinel_my_net Created 0.0s
⠿ Container redis_master Created 0.0s
⠿ Container redis_node_2 Created 0.0s
⠿ Container redis_node_1 Created 0.0s
⠿ Container redis_sentinel_1 Created 0.0s
⠿ Container redis_sentinel_2 Created 0.0s
⠿ Container redis_sentinel_3 Created 0.0s
Attaching to redis_master, redis_node_1, redis_node_2, redis_sentinel_1, redis_sentinel_2, redis_sentinel_3
...
redis_sentinel_1 | 1:X 13 Oct 2022 10:12:52.996 # Sentinel ID is 141d777f9984c5aa5f5e6f82fd6d9dc9e865c51d
redis_sentinel_1 | 1:X 13 Oct 2022 10:12:52.996 # +monitor master the_master 172.25.0.10 6379 quorum 2
...
redis_sentinel_2 | 1:X 13 Oct 2022 10:12:53.146 # Sentinel ID is a1df19e38db034efd18add95b7bbcf6bbc6000d5
redis_sentinel_2 | 1:X 13 Oct 2022 10:12:53.146 # +monitor master the_master 172.25.0.10 6379 quorum 2
...
redis_sentinel_3 | 1:X 13 Oct 2022 10:12:53.203 # Sentinel ID is 6ba1b24f82a3e53d7fcb1e3ff9f51292c4c24440
redis_sentinel_3 | 1:X 13 Oct 2022 10:12:53.203 # +monitor master the_master 172.25.0.10 6379 quorum 2
注:如果之前 /home/docker/redis_cluster/replication 目录下运行的 docker-compose up 还在运行,需要先回到 /home/docker/redis_cluster/replication 目录下运行 docker-compose down。
控制台(Console 1)处于阻塞状态,redis_sentinel_1、redis_sentinel_2 和 redis_sentinel_3 监控 master 的状态。
4) 模拟 master 节点故障
可以暂停 redis_master 的容器,打开一个新的控制台(Console 2):
$ docker pause redis_master
以上命令运行后,控制台(Console 1)阻塞状态结束阻塞,新显示内容如下:
...
redis_node_1 | 9:S 13 Oct 2022 10:14:34.075 * MASTER <-> REPLICA sync: Master accepted a Partial Resynchronization.
redis_sentinel_2 | 1:X 13 Oct 2022 10:14:34.965 * +slave-reconf-inprog slave 172.25.0.11:6380 172.25.0.11 6380 @ the_master 172.25.0.10 6379
redis_sentinel_2 | 1:X 13 Oct 2022 10:14:34.965 * +slave-reconf-done slave 172.25.0.11:6380 172.25.0.11 6380 @ the_master 172.25.0.10 6379
redis_sentinel_2 | 1:X 13 Oct 2022 10:14:35.055 # -odown master the_master 172.25.0.10 6379
redis_sentinel_2 | 1:X 13 Oct 2022 10:14:35.055 # +failover-end master the_master 172.25.0.10 6379
redis_sentinel_2 | 1:X 13 Oct 2022 10:14:35.055 # +switch-master the_master 172.25.0.10 6379 172.25.0.12 6381
redis_sentinel_2 | 1:X 13 Oct 2022 10:14:35.055 * +slave slave 172.25.0.11:6380 172.25.0.11 6380 @ the_master 172.25.0.12 6381
redis_sentinel_2 | 1:X 13 Oct 2022 10:14:35.055 * +slave slave 172.25.0.10:6379 172.25.0.10 6379 @ the_master 172.25.0.12 6381
redis_sentinel_1 | 1:X 13 Oct 2022 10:15:04.122 # +sdown slave 172.25.0.10:6379 172.25.0.10 6379 @ the_master 172.25.0.12 6381
redis_sentinel_3 | 1:X 13 Oct 2022 10:15:04.122 # +sdown slave 172.25.0.10:6379 172.25.0.10 6379 @ the_master 172.25.0.12 6381
redis_sentinel_2 | 1:X 13 Oct 2022 10:15:05.079 # +sdown slave 172.25.0.10:6379 172.25.0.10 6379 @ the_master 172.25.0.12 6381
6. Cluster 集群
1) Cluster 配置文件
Redis Cluster 官方建议最少 6 个节点,准备如下 6 个节点。
(1) 创建 node_3 的 redis.conf 文件
在 /home/docker/redis_cluster/node_3/conf 目录下,创建 redis.conf 文件,内容如下:
bind 0.0.0.0
port 6379
protected-mode no
slave-read-only no
logfile /var/log/redis.log
#dir /data
cluster-enabled yes
cluster-config-file node-3.conf
masterauth pass123
requirepass pass123
(2) 创建 node_4 的 redis.conf 文件
在 /home/docker/redis_cluster/node_4/conf 目录下,创建 redis.conf 文件,内容如下:
bind 0.0.0.0
port 6379
protected-mode no
slave-read-only no
logfile /var/log/redis.log
#dir /data
cluster-enabled yes
cluster-config-file node-4.conf
masterauth pass123
requirepass pass123
(3) 创建 node_5 的 redis.conf 文件
在 /home/docker/redis_cluster/node_5/conf 目录下,创建 redis.conf 文件,内容如下:
bind 0.0.0.0
port 6379
protected-mode no
slave-read-only no
logfile /var/log/redis.log
#dir /data
cluster-enabled yes
cluster-config-file node-5.conf
masterauth pass123
requirepass pass123
(4) 创建 node_6 的 redis.conf 文件
在 /home/docker/redis_cluster/node_6/conf 目录下,创建 redis.conf 文件,内容如下:
bind 0.0.0.0
port 6379
protected-mode no
slave-read-only no
logfile /var/log/redis.log
#dir /data
cluster-enabled yes
cluster-config-file node-6.conf
masterauth pass123
requirepass pass123
(5) 创建 node_7 的 redis.conf 文件
在 /home/docker/redis_cluster/node_7/conf 目录下,创建 redis.conf 文件,内容如下:
bind 0.0.0.0
port 6379
protected-mode no
slave-read-only no
logfile /var/log/redis.log
#dir /data
cluster-enabled yes
cluster-config-file node-7.conf
masterauth pass123
requirepass pass123
(6) 创建 node_8 的 redis.conf 文件
在 /home/docker/redis_cluster/node_8/conf 目录下,创建 redis.conf 文件,内容如下:
bind 0.0.0.0
port 6379
protected-mode no
slave-read-only no
logfile /var/log/redis.log
#dir /data
cluster-enabled yes
cluster-config-file node-8.conf
masterauth pass123 # 主从认证密码
requirepass pass123 # 本地认证密码
2) 修改 common.env 文件
在 /home/docker/redis_cluster 目录下,修改 common.env 文件,内容如下:
REQUIRE_PASS=123456
MASTER_AUTH=123456
MASTER_HOST=redis_master
MASTER_PORT=6379
CLUSTER_HOSTS=172.25.0.13:6379 172.25.0.14:6379 172.25.0.15:6379 172.25.0.16:6379 172.25.0.17:6379 172.25.0.18:6379
CLUSTER_PASS=pass123
3) 修改 run_redis_server.sh 文件
在 /home/docker/redis_cluster/scripts 目录下,修改 run_redis_server.sh 文件,内容如下:
#!/bin/bash
if [[ $1 = 'master' ]]; then
redis-server /etc/redis/redis.conf --requirepass $REQUIRE_PASS --masterauth $MASTER_AUTH
elif [[ $1 = 'slave' ]]; then
redis-server /etc/redis/redis.conf --slaveof $MASTER_HOST $MASTER_PORT --requirepass $REQUIRE_PASS --masterauth $MASTER_AUTH
elif [[ $1 = 'cluster_normal' ]]; then
redis-server /etc/redis/redis.conf
elif [[ $1 = 'cluster_special' ]]; then
redis-server /etc/redis/redis.conf
echo "yes" | redis-cli --cluster create $CLUSTER_HOSTS --cluster-replicas 1 -a $CLUSTER_PASS
else
echo "Usage: $0 [master|slave|cluster_normal|cluster_special]"
echo " master - Redis master"
echo " slave - Redis slave"
echo " cluster_normal - Redis cluster normal node"
echo " cluster_special - Redis cluster special node"
echo ""
fi
4) 创建 docker-compose.yml
在 /home/docker/redis_cluster/cluster 目录下,创建 docker-compose.yml 文件,内容如下:
version: "3"
services:
redis_node_3:
image: redis:6
container_name: redis_node_3
volumes:
- /home/docker/redis_cluster/node_3/data:/data
- /home/docker/redis_cluster/node_3/conf:/etc/redis
- /home/docker/redis_cluster/node_3/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.13
command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_normal
env_file:
- /home/docker/redis_cluster/common.env
redis_node_4:
image: redis:6
container_name: redis_node_4
volumes:
- /home/docker/redis_cluster/node_4/data:/data
- /home/docker/redis_cluster/node_4/conf:/etc/redis
- /home/docker/redis_cluster/node_4/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.14
command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_normal
env_file:
- /home/docker/redis_cluster/common.env
redis_node_5:
image: redis:6
container_name: redis_node_5
volumes:
- /home/docker/redis_cluster/node_5/data:/data
- /home/docker/redis_cluster/node_5/conf:/etc/redis
- /home/docker/redis_cluster/node_5/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.15
command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_normal
env_file:
- /home/docker/redis_cluster/common.env
redis_node_6:
image: redis:6
container_name: redis_node_6
volumes:
- /home/docker/redis_cluster/node_6/data:/data
- /home/docker/redis_cluster/node_6/conf:/etc/redis
- /home/docker/redis_cluster/node_6/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.16
command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_normal
env_file:
- /home/docker/redis_cluster/common.env
redis_node_7:
image: redis:6
container_name: redis_node_7
volumes:
- /home/docker/redis_cluster/node_7/data:/data
- /home/docker/redis_cluster/node_7/conf:/etc/redis
- /home/docker/redis_cluster/node_7/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.17
command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_normal
env_file:
- /home/docker/redis_cluster/common.env
redis_node_8:
image: redis:6
container_name: redis_node_8
depends_on:
- redis_node_3
- redis_node_4
- redis_node_5
- redis_node_6
- redis_node_7
volumes:
- /home/docker/redis_cluster/node_8/data:/data
- /home/docker/redis_cluster/node_8/conf:/etc/redis
- /home/docker/redis_cluster/node_8/log:/var/log
- /home/docker/redis_cluster/scripts:/root/redis_scripts
networks:
my_net:
ipv4_address: 172.25.0.18
command: /bin/bash /root/redis_scripts/run_redis_server.sh cluster_special
env_file:
- /home/docker/redis_cluster/common.env
networks:
my_net:
driver: bridge
ipam:
config:
- subnet: 172.25.0.0/16
5) 启动
$ cd /home/docker/redis_cluster/cluster
$ docker-compose up -d
[+] Running 7/7
⠿ Network cluster_my_net Created 0.0s
⠿ Container redis_node_6 Started 0.8s
⠿ Container redis_node_7 Started 0.7s
⠿ Container redis_node_3 Started 0.8s
⠿ Container redis_node_4 Started 1.0s
⠿ Container redis_node_5 Started 1.0s
⠿ Container redis_node_8 Started 1.6s
$ docker exec -it redis_node_8 /bin/bash
root@754fb446b99f:/data# redis-cli -c
127.0.0.1:6379> auth pass123
OK
127.0.0.1:6379> cluster info
cluster_state:ok
cluster_slots_assigned:16384
cluster_slots_ok:16384
cluster_slots_pfail:0
cluster_slots_fail:0
cluster_known_nodes:6
cluster_size:3
cluster_current_epoch:6
cluster_my_epoch:2
cluster_stats_messages_ping_sent:37
cluster_stats_messages_pong_sent:38
cluster_stats_messages_sent:75
cluster_stats_messages_ping_received:38
cluster_stats_messages_pong_received:37
cluster_stats_messages_received:75
127.0.0.1:6379> cluster nodes
4a93001b49bb2138c0a2c7f67369e47f1762ae7d 172.25.0.18:6379@16379 myself,slave c1095cc3609d0043fb8f7db7d2e728f89c19c5ee 0 1665898497000 2 connected
c1095cc3609d0043fb8f7db7d2e728f89c19c5ee 172.25.0.14:6379@16379 master - 0 1665898499256 2 connected 5461-10922
98c22d70fedf2332629df0e065d5fa5dfbaa9964 172.25.0.16:6379@16379 slave d1604ceeb5fa2474e779468bb6f4566c1adee365 0 1665898497000 3 connected
d1604ceeb5fa2474e779468bb6f4566c1adee365 172.25.0.15:6379@16379 master - 0 1665898498228 3 connected 10923-16383
c2f940037de7ff3a0b05611a9b70f56f0afa7a09 172.25.0.13:6379@16379 master - 0 1665898496171 1 connected 0-5460
1c834e5fbe2f61029f55a53e6f517ec8dcf87833 172.25.0.17:6379@16379 slave c2f940037de7ff3a0b05611a9b70f56f0afa7a09 0 1665898497193 1 connected
可以看到 redis_node_3、redis_node_4、redis_node_5 是 master,redis_node_6、redis_node_7、redis_node_8 是 slave。进入任意从节点,执行 info replicaiton 来再次验证。
$ docker exec -it redis_node_6 /bin/bash
root@15ccf6f9c9b8:/data# redis-cli -c
127.0.0.1:6379> auth pass123
OK
127.0.0.1:6379> info replication
# Replication
role:slave
master_host:172.25.0.15
master_port:6379
master_link_status:up
master_last_io_seconds_ago:9
master_sync_in_progress:0
slave_read_repl_offset:924
slave_repl_offset:924
slave_priority:100
slave_read_only:0
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:f64ceb5694da9afbd96ec4fe96eb07f17d2f7922
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:924
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:924
浙公网安备 33010602011771号