文章目录
- 1 整体拓扑图
- 2 redis与哨兵配置文件
- 2.1 主节点配置文件
- 2.1.1 主节点redis.conf配置文件
- 2.1.2 主节点哨兵配置文件
- 2.2 从节点配置文件
- 2.1.1 从节点redis.conf配置文件
- 2.1.2 从节点哨兵配置文件
- 3 docke-compose编排文件
- 4 启动并测试
- 查看哨兵日志
- 查看集群状态
- 测试集群是否同步
- 测试哨兵选举能力
- 5 注意事项
redis经典的集群结构:一主两从三哨兵,由于平时习惯与部门规范,需要使用docker容器进行搭建。
1 整体拓扑图
可见,三个服务器之间的docker是完全隔离的,我们需要打通docker,或者通过docker的host模式进行访问。
2 redis与哨兵配置文件
2.1 主节点配置文件
2.1.1 主节点redis.conf配置文件
主节点按理说是不需要配置masterauth
的,但是为什么主节点也要配置呢?
原因是主节点宕机后,会有其他从节点变成主节点,这是我们重启主节点后,哨兵会将我们变为从节点,这时加入到新的主节点后是需要密码的。
redis.conf示例:
# 自定义端口
port 8094
# 密码
requirepass "admin"
# 持久化
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename "dump.rdb"
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
# 主节点密码
masterauth "admin"
2.1.2 主节点哨兵配置文件
这里的配置的密码与上面同理
sentinel.conf示例:
# 哨兵端口
port 8095
# 开启守护线程
daemonize yes
# 与redis主节点通信 ip 端口 选举master时的quorum值
sentinel monitor mymaster 172.16.0.81 8094 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
# 关闭保护模式
protected-mode no
# 主节点密码
sentinel auth-pass mymaster admin
# 日志位置
logfile "/usr/local/redis/sentinel.log"
2.2 从节点配置文件
2.1.1 从节点redis.conf配置文件
两个从节点配置完全相同
初始化时,从节点需要加入到主节点:replicaof 172.16.0.81 8094
redis.conf示例:
# 自定义端口
port 8094
# 密码
requirepass "admin"
# 持久化
save 900 1
save 300 10
save 60 10000
rdbcompression yes
dbfilename "dump.rdb"
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
# 主节点密码
masterauth "admin"
# 加入到主节点
replicaof 172.16.0.81 8094
2.1.2 从节点哨兵配置文件
这里的配置的密码与上面同理
sentinel.conf示例:
# 哨兵端口
port 8095
# 开启守护线程
daemonize yes
# 与redis主节点通信 ip 端口 选举master时的quorum值
sentinel monitor mymaster 172.16.0.81 8094 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
# 关闭保护模式
protected-mode no
# 主节点密码
sentinel auth-pass mymaster admin
# 日志位置
logfile "/usr/local/redis/sentinel.log"
3 docke-compose编排文件
三个节点编排文件完全一致
目录结构:
redis
├── conf
│ ├── redis.conf
│ └── sentinel.conf
├── data
│ ├── appendonly.aof
│ ├── dump.rdb
│ └── temp-1675068389.10.rdb
└── docker-compose.yml
docker-compose.yml示例:
version: "3"
services:
redis:
image: redis:6.2.6
volumes:
- ./conf:/usr/local/redis/conf/
- ./data:/data/
environment:
TZ: Asia/Shanghai
restart: always
network_mode: host
command:
- sh
- -c
- |
redis-sentinel /usr/local/redis/conf/sentinel.conf
redis-server /usr/local/redis/conf/redis.conf
command下代表串行执行两个命令,如果需要并行:
command:
- sh
- -c
- |
redis-sentinel /usr/local/redis/conf/sentinel.conf &
redis-server /usr/local/redis/conf/redis.conf
4 启动并测试
三个节点分别使用docker-compose up -d
启动
查看哨兵日志
docker-compose exec redis tail -f /usr/local/redis/sentinel.log
发现已经找到了两个从节点和其余两个哨兵
9:X 30 Jan 2023 18:06:10.586 # Configuration loaded
9:X 30 Jan 2023 18:06:10.587 * monotonic clock: POSIX clock_gettime
9:X 30 Jan 2023 18:06:10.588 * Running mode=sentinel, port=8095.
9:X 30 Jan 2023 18:06:10.588 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
9:X 30 Jan 2023 18:06:10.588 # Sentinel ID is d51d174841dc2be296b18359b05f181a1675f1f6
9:X 30 Jan 2023 18:06:10.588 # +monitor master mymaster 172.16.0.81 8094 quorum 2
9:X 30 Jan 2023 18:06:17.293 * +sentinel sentinel 08323b3dfe0150a0a0d31d59bf21b30706a7fc83 172.16.0.84 8095 @ mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:06:21.710 * +slave slave 172.16.0.84:8094 172.16.0.84 8094 @ mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:06:21.712 * +slave slave 172.16.0.82:8094 172.16.0.82 8094 @ mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:06:22.305 * +sentinel sentinel 728694c0bfccdc12f5e82d17bf9aebd2aeedac69 172.16.0.82 8095 @ mymaster 172.16.0.81 8094
查看集群状态
使用redis-cli查看主节点:info replication
role:master
connected_slaves:2
slave0:ip=172.16.0.84,port=8094,state=online,offset=33332,lag=1
slave1:ip=172.16.0.82,port=8094,state=online,offset=33332,lag=1
master_failover_state:no-failover
master_replid:3f89e662faf55bfde5e0fb0ce11b96ef638ff71b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:33468
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:33468
使用redis-cli查看从节点:info replication
role:slave
master_host:172.16.0.81
master_port:8094
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_read_repl_offset:58524
slave_repl_offset:58524
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:3f89e662faf55bfde5e0fb0ce11b96ef638ff71b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:58524
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:58524
测试集群是否同步
在主节点添加key,在从节点上可以读取
测试哨兵选举能力
这时我们停掉主节点:docker-compose stop
然后去从节点查看哨兵日志:docker-compose exec redis tail -f /usr/local/redis/sentinel.log
通过日志发现已经选举出来的新的主节点:
9:X 30 Jan 2023 18:19:46.731 # +sdown master mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:46.731 # +sdown sentinel d51d174841dc2be296b18359b05f181a1675f1f6 172.16.0.81 8095 @ mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:46.832 # +odown master mymaster 172.16.0.81 8094 #quorum 2/2
9:X 30 Jan 2023 18:19:46.832 # +new-epoch 1
9:X 30 Jan 2023 18:19:46.832 # +try-failover master mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:46.834 # +vote-for-leader 08323b3dfe0150a0a0d31d59bf21b30706a7fc83 1
9:X 30 Jan 2023 18:19:46.839 # 728694c0bfccdc12f5e82d17bf9aebd2aeedac69 voted for 08323b3dfe0150a0a0d31d59bf21b30706a7fc83 1
9:X 30 Jan 2023 18:19:46.918 # +elected-leader master mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:46.918 # +failover-state-select-slave master mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:47.009 # +selected-slave slave 172.16.0.84:8094 172.16.0.84 8094 @ mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:47.009 * +failover-state-send-slaveof-noone slave 172.16.0.84:8094 172.16.0.84 8094 @ mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:47.062 * +failover-state-wait-promotion slave 172.16.0.84:8094 172.16.0.84 8094 @ mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:47.863 # +promoted-slave slave 172.16.0.84:8094 172.16.0.84 8094 @ mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:47.863 # +failover-state-reconf-slaves master mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:47.937 * +slave-reconf-sent slave 172.16.0.82:8094 172.16.0.82 8094 @ mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:48.883 * +slave-reconf-inprog slave 172.16.0.82:8094 172.16.0.82 8094 @ mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:48.883 * +slave-reconf-done slave 172.16.0.82:8094 172.16.0.82 8094 @ mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:48.938 # -odown master mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:48.938 # +failover-end master mymaster 172.16.0.81 8094
9:X 30 Jan 2023 18:19:48.938 # +switch-master mymaster 172.16.0.81 8094 172.16.0.84 8094
9:X 30 Jan 2023 18:19:48.938 * +slave slave 172.16.0.82:8094 172.16.0.82 8094 @ mymaster 172.16.0.84 8094
9:X 30 Jan 2023 18:19:48.938 * +slave slave 172.16.0.81:8094 172.16.0.81 8094 @ mymaster 172.16.0.84 8094
9:X 30 Jan 2023 18:19:53.996 # +sdown slave 172.16.0.81:8094 172.16.0.81 8094 @ mymaster 172.16.0.84 8094
然后重启之前的主节点:docker-compose start
,这时之前的主节点已经变为从节点,经过测试,没有问题。
至此,完美撒花!
5 注意事项
注意注意注意:
使用docker时,如果不使用host网络模式,那么会有哨兵之间访问不通,也就是哨兵失效的问题。
问题复现:
docker容器内端口6379:映射到宿主机8094,那么!!!
在从节点向主节点注册时,注册的ip是宿主机的ip,端口则是容器内部的端口,你说坑不坑!
然后哨兵则会去主节点找相关从节点的信息,获取到的就是
宿主机的ip+容器内部的端口
,讲道理,这根本不通的好吗!跨服务器docker的完全隔离的
解决方案
方案1:不使用docker,使用原生,是比较好的方案,但是我们公司的场景不允许
方案2:打通不同主机下docker网络,成本太高,不适用
方案3:修改redis配置文件,使容器内和映射出来的端口完全一致,啊这。。。有点舍近求远,而且只是曲线救国,掩盖了问题,不太好,pass了。
方案4:使用host网络模式:
network_mode: host
,这样docker容器会使用宿主机的ip和端口,嗯。。。这样就不用映射了,想改端口直接修改配置文件就行了,挺好
在一主两从三哨兵集群模式模式中,哨兵会动态修改我们的配置文件,如果有主节点挂了,那么哨兵会自动帮我们把新的主节点写入到配置文件中。