欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 社会 > 实战使用Docker compose搭建Redis哨兵(Sentinel)模式集群

实战使用Docker compose搭建Redis哨兵(Sentinel)模式集群

2025/6/20 6:52:41 来源:https://blog.csdn.net/weixin_39970883/article/details/148762085  浏览:    关键词:实战使用Docker compose搭建Redis哨兵(Sentinel)模式集群

文章目录

    • 前言
    • 技术积累
      • 什么是Redis的哨兵模式
      • 哨兵的三个任务
      • 哨兵选主流程
      • 哨兵模式存在的问题
    • 实战演示
      • 部署环境
      • 创建目录
      • 编写Redis配置文件
      • 编写哨兵配置文件
      • 编写Docker-Compose.yml
      • 启动Redis Sentinel容器
        • 执行yml文件
        • 查看容器状态
      • 查看Redis各个角色状态
        • 查看主节点信息
        • 查看从节点信息
        • 查看哨兵的信息
      • 主从复制验证
      • 验证sentinel自动故障转移
        • 1、查看当前主节点
        • 2、停止主节点
        • 3、查看是否故障转移,是否选除了主节点
        • 4、继续验证slave2角色
        • 5、启动redis-master
        • 6、查看主节点是否加入集群且为从库角色
    • 总结

前言

Redis 是一个高性能的键值存储系统,常用于缓存、消息队列等场景。为了保证高可用性,Redis 提供了哨兵模式(Sentinel)来实现主从切换和故障转移。本文将介绍如何使用 docker-compose 快速搭建 Redis 主从 + 哨兵集群环境。

在这里插入图片描述

技术积累

什么是Redis的哨兵模式

Redis的哨兵模式,就是在主从模式的基础上,额外部署若干独立的哨兵进程,通过哨兵进程去监视者Redis主从节点的状态,一旦发现主节点宕机,则哨兵可以重新从剩余slave节点中推选一个新的节点并将其升级为master节点,以此保证整个系统功能可以正常使用。

哨兵的三个任务

哨兵负责三个任务:监控,选主和通知。

  • 监控:监控是指哨兵进程运行时,周期性(默认1秒)给所有主从节点发送 PING 命令,当主从节点收到 PING 命令后,会发送一个响应命令给哨兵,这样就可以检测他们是否仍然在线运行。
    • 从库没有在规定时间内响应哨兵的PING命令,哨兵就会把它标记为"下线状态";
    • 主库没有在规定时间呢响应哨兵的PING命令,哨兵就会判定主库下线启动选主流程。
  • 选主:哨兵在主库挂了以后,按照一定规则从从库中选出作为新的主库。
  • 通知:哨兵将选出的新主库连接信息发给其他从库,从库和新主库建立连接,执行replicaof命令,复制数据。同时,哨兵会把新主库的连接信息通知给客户端,让它们将操作请求发送给新主库上。

哨兵选主流程

哨兵机制具体步骤如下:
1、哨兵集群第一轮投票:判断主节点客观下线;
2、哨兵集群第二轮投票:选出哨兵leader,决定由哪个哨兵执行主从切换;
3、由哨兵 leader 进行选主;
4、由哨兵 leader 进行通知,实现主从故障转移。

哨兵模式存在的问题

在主从复制的基础上,哨兵引入了主节点的自动故障转移,进一步提高了Redis的高可用性;但是哨兵的缺陷同样很明显:
1、哨兵无法对从节点进行自动故障转移,在读写分离场景下,从节点故障会导致读服务不可用;
2、哨兵仍然没有解决写操作无法负载均衡、存储能力受到单机限制的问题,如果需要解决这些问题就是使用Redis Cluster集群。

实战演示

部署环境

Redis哨兵模式,一主二从三哨兵
Redis主节点(6379)
Redis从节点1(6380)
Redis从节点2(6381)
Redis哨兵1(26379)
Redis哨兵2(26380)
Redis哨兵3(26381)

创建目录

在这里插入图片描述

编写Redis配置文件

  • redis-master
# 主节点配置
# 绑定的主机地址
bind 0.0.0.0
# 允许外网访问
protected-mode no
# 启用守护进程后,Redis会把pid写到一个pidfile中,在/var/run/redis.pid
daemonize no
# 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
pidfile /var/run/redis.pid
# 指定Redis监听端口,默认端口为6379
# 如果指定0端口,表示Redis不监听TCP连接
port 6379
# 当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
timeout 0
# 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
# debug (很多信息, 对开发/测试比较有用)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel verbose
# 日志记录方式,默认为标准输出,如果配置为redis为守护进程方式运行,而这里又配置为标准输出,则日志将会发送给/dev/null
logfile redis.log################################ SNAPSHOTTING  #################################
# RDB存储配置
# 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   满足以下条件将会同步数据:
#   900秒(15分钟)内有1个更改
#   300秒(5分钟)内有10个更改
#   60秒内有10000个更改
#   Note: 可以把所有“save”行注释掉,这样就取消同步操作了
save 900 1
save 300 10
save 60 10000
# 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
rdbcompression yes
# 指定本地数据库文件名,默认值为dump.rdb
dbfilename dump.rdb
# 指定本地数据库存放目录,文件名由上一个dbfilename配置项指定
dir /data################################# REPLICATION ################################################################### SECURITY ###################################
# 设置密码
requirepass 123456789############################## APPEND ONLY MODE ###############################
# 开启aof配置
appendonly yes
# 指定更新日志条件,共有3个可选值:
# no:表示等操作系统进行数据缓存同步到磁盘(快)
# always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
# everysec:表示每秒同步一次(折衷,默认值)
appendfsync everysec
# 指定更新日志文件名,默认为appendonly.aof
appendfilename "appendonly.aof"
  • redis-slave1
# 从节点配置
# 绑定的主机地址
bind 0.0.0.0
# 允许外网访问
protected-mode no
# 启用守护进程后,Redis会把pid写到一个pidfile中,在/var/run/redis.pid
daemonize no
# 当Redis以守护进程方式运行时,Redis默认会把pid写入/var/run/redis.pid文件,可以通过pidfile指定
pidfile /var/run/redis.pid
# 指定Redis监听端口,默认端口为6379
# 如果指定0端口,表示Redis不监听TCP连接
port 6379
# 当客户端闲置多长时间后关闭连接,如果指定为0,表示关闭该功能
timeout 0
# 指定日志记录级别,Redis总共支持四个级别:debug、verbose、notice、warning,默认为verbose
# debug (很多信息, 对开发/测试比较有用)
# verbose (many rarely useful info, but not a mess like the debug level)
# notice (moderately verbose, what you want in production probably)
# warning (only very important / critical messages are logged)
loglevel verbose
# 日志记录方式,默认为标准输出,如果配置为redis为守护进程方式运行,而这里又配置为标准输出,则日志将会发送给/dev/null
logfile redis.log################################ SNAPSHOTTING  #################################
# RDB存储配置
# 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   满足以下条件将会同步数据:
#   900秒(15分钟)内有1个更改
#   300秒(5分钟)内有10个更改
#   60秒内有10000个更改
#   Note: 可以把所有“save”行注释掉,这样就取消同步操作了
save 900 1
save 300 10
save 60 10000
# 指定存储至本地数据库时是否压缩数据,默认为yes,Redis采用LZF压缩,如果为了节省CPU时间,可以关闭该选项,但会导致数据库文件变的巨大
rdbcompression yes
# 指定本地数据库文件名,默认值为dump.rdb
dbfilename dump.rdb
# 指定本地数据库存放目录,文件名由上一个dbfilename配置项指定
dir /data################################# REPLICATION #################################
# 设置当本机为slav服务时,设置master服务的ip地址及端口,在Redis启动时,它会自动从master进行数据同步
replicaof redis-master 6379
# 开启只读模式
replica-read-only yes
# 当master服务设置了密码保护时,slav服务连接master的密码
masterauth 123456789repl-diskless-load on-empty-db################################## SECURITY ###################################
# 设置密码
requirepass 123456789############################## APPEND ONLY MODE ###############################
# 开启aof配置
appendonly yes
# 指定更新日志条件,共有3个可选值:
# no:表示等操作系统进行数据缓存同步到磁盘(快)
# always:表示每次更新操作后手动调用fsync()将数据写到磁盘(慢,安全)
# everysec:表示每秒同步一次(折衷,默认值)
appendfsync everysec
# 指定更新日志文件名,默认为appendonly.aof
appendfilename "appendonly.aof"
  • redis-slave2 与slave1一致即可

编写哨兵配置文件

  • reids-sentinel1.conf
# 服务端口
port 26379
# 可访问IP
bind 0.0.0.0
# By default Redis Sentinel does not run as a daemon. Use 'yes' if you need it.
daemonize no# When running daemonized, Redis Sentinel writes a pid file in
# /var/run/redis-sentinel.pid by default. You can specify a custom pid file
# location here.
pidfile /var/run/redis-sentinel.pid# Specify the log file name. Also the empty string can be used to force
# Sentinel to log on the standard output. Note that if you use standard
logfile "sentinel.log"# dir <working-directory>
dir /tmp# 监控的主机(格式为 sentinel monitor 主机名 主机ip 主机端口 多少个哨兵节点都认为主节点不可达时才会进行故障转移的数量)
sentinel monitor redis-master 172.16.8.212 6379 2# 监控的主机密码(格式为 sentinel auth-pass 主机名 主机连接密码)
sentinel auth-pass redis-master 123456789# 指定在多少毫秒内,哨兵节点没有收到主节点的响应时,就会将主节点判定为下线状态(格式为 sentinel down-after-milliseconds >主机名 超时毫秒数)
sentinel down-after-milliseconds redis-master 30000# ACL LOG
acllog-max-len 128# 指定在进行故障转移时可以同时同步的从节点数量(格式为 sentinel parallel-syncs 主机名 主机连接密码)
sentinel parallel-syncs redis-master 1# 指定进行故障转移的超时时间,即在多少毫秒内完成故障转移操作(格式为 sentinel failover-timeout 主机名 主机连接密码)
sentinel failover-timeout redis-master 180000# SECURITY
# By default SENTINEL SET will not be able to change the notification-script
# and client-reconfig-script at runtime. This avoids a trivial security issue
# where clients can set the script to anything and trigger a failover in order
# to get the program executed.sentinel deny-scripts-reconfig yes# You may enable hostnames support by enabling resolve-hostnames. Note
# that you must make sure your DNS is configured properly and that DNS
# resolution does not introduce very long delays.
SENTINEL resolve-hostnames no# When resolve-hostnames is enabled, Sentinel still uses IP addresses
# when exposing instances to users, configuration files, etc. If you want
# to retain the hostnames when announced, enable announce-hostnames below.
SENTINEL announce-hostnames no
  • redis-sentinel2.conf 复制一份sentinel1
  • redis-sentinel3.conf 复制一份sentinel1

编写Docker-Compose.yml

version: '3.8'services:redis-master:image: redis:6-alpinecontainer_name: redis-masterenvironment:- "TZ=Asia/Shanghai"ports:- "6379:6379"volumes:- ./redis-master/conf/redis.conf:/usr/local/etc/redis/redis.conf- ./redis-master/data:/data- ./redis-master/logs:/logscommand: redis-server /usr/local/etc/redis/redis.confnetworks:- redis-sentinelredis-slave1:image: redis:6-alpinecontainer_name: redis-slave1environment:- "TZ=Asia/Shanghai"ports:- "6380:6379"volumes:- ./redis-slave1/conf/redis.conf:/usr/local/etc/redis/redis.conf- ./redis-slave1/data:/data- ./redis-slave1/logs:/logscommand: redis-server /usr/local/etc/redis/redis.confdepends_on:- redis-masternetworks:- redis-sentinelredis-slave2:image: redis:6-alpinecontainer_name: redis-slave2environment:- "TZ=Asia/Shanghai"ports:- "6381:6379"volumes:- ./redis-slave2/conf/redis.conf:/usr/local/etc/redis/redis.conf- ./redis-slave2/data:/data- ./redis-slave2/logs:/logscommand: redis-server /usr/local/etc/redis/redis.confdepends_on:- redis-masternetworks:- redis-sentinelredis-sentinel1:image: redis:6-alpinecontainer_name: redis-sentinel1environment:- "TZ=Asia/Shanghai"    ports:- '26379:26379'volumes:- ./redis-sentinel1/data:/data- ./redis-sentinel1/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf- ./redis-sentinel1/logs:/logscommand: redis-sentinel /usr/local/etc/redis/sentinel.confdepends_on: - redis-master- redis-slave1- redis-slave2networks:- redis-sentinelredis-sentinel2:image: redis:6-alpinecontainer_name: redis-sentinel2environment:- "TZ=Asia/Shanghai"ports:- '26380:26379'volumes:- ./redis-sentinel2/data:/data- ./redis-sentinel2/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf- ./redis-sentinel2/logs:/logscommand: redis-sentinel /usr/local/etc/redis/sentinel.confdepends_on: - redis-master- redis-slave1- redis-slave2networks:- redis-sentinelredis-sentinel3:image: redis:6-alpinecontainer_name: redis-sentinel3environment:- "TZ=Asia/Shanghai"ports:- '26381:26379'volumes:- ./redis-sentinel3/data:/data- ./redis-sentinel3/conf/sentinel.conf:/usr/local/etc/redis/sentinel.conf- ./redis-sentinel3/logs:/logscommand: redis-sentinel /usr/local/etc/redis/sentinel.confdepends_on: - redis-master- redis-slave1- redis-slave2networks:- redis-sentinelnetworks:redis-sentinel:driver: bridge

启动Redis Sentinel容器

执行yml文件
docker-compose -f docker-compose.yaml up -d

在这里插入图片描述

查看容器状态
docker ps -a

在这里插入图片描述

可以看到所有容器都已经成功启动了

查看Redis各个角色状态

  • info replication 查看Redis节点信息
  • info sentinel 查看Redis哨兵信息
查看主节点信息
docker exec -it redis-master redis-cli -h 127.0.0.1 -p 6379 -a 123456789 info replication

在这里插入图片描述

列出了其两个从节点信息

查看从节点信息
docker exec -it redis-slave1 redis-cli -h 127.0.0.1 -p 6379 -a 123456789 info replication

在这里插入图片描述

可以看到当前从节点信息

查看哨兵的信息

进入sentinel容器查看

docker exec -it redis-sentinel1 redis-cli -h 127.0.0.1 -p 26379  info sentinel

在这里插入图片描述

可以看到主节点信息、状态和Redis的配置详情(两个从节点,三个哨兵)

主从复制验证

写入数据到主节点

docker exec -it redis-master redis-cli -h 127.0.0.1 -p 6379 -a 123456789 SET name "test_senfel_data"

主节点读取数据查看是否设置成功

docker exec -it redis-master redis-cli -h 127.0.0.1 -p 6379 -a 123456789 GET name

从节点1读取数据,查看是否同步

docker exec -it redis-slave1 redis-cli -h 127.0.0.1 -p 6379 -a 123456789 GET name

从节点2读取数据,查看是否同步

docker exec -it redis-slave2 redis-cli -h 127.0.0.1 -p 6379 -a 123456789 GET name

在这里插入图片描述

验证sentinel自动故障转移

1、查看当前主节点
docker exec -it redis-sentinel1 redis-cli -h 127.0.0.1 -p 26379  info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=redis-master,status=ok,address=172.16.8.212:6379,slaves=2,sentinels=3

主节点是 redis-master

2、停止主节点
docker stop redis-master 
D:\A-senfel\docker-data\redis\redis-sentinel>docker stop redis-master
redis-master
3、查看是否故障转移,是否选除了主节点
docker exec -it redis-sentinel1 redis-cli -h 127.0.0.1 -p 26379  info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=redis-master,status=ok,address=172.20.0.3:6379,slaves=2,sentinels=3

发现master地址已经变为了slave2的内网地址。

4、继续验证slave2角色
docker exec -it redis-slave2 redis-cli -h 127.0.0.1 -p 6379 -a 123456789 info replication

在这里插入图片描述

可以确定已经自动故障转移成功,master切换到slave2节点。

5、启动redis-master
docker start redis-master
D:\A-senfel\docker-data\redis\redis-sentinel>docker start redis-master
redis-master
6、查看主节点是否加入集群且为从库角色
docker exec -it redis-master redis-cli -h 127.0.0.1 -p 6379 -a 123456789 info replication

在这里插入图片描述

如上所述,重启后的库已将加入集群。

总结

通过 docker-compose 可以快速搭建 Redis 哨兵模式,适用于开发、测试及轻量级生产环境。该方案具备的优点是易于部署和维护、支持自动故障转移、数据多副本,提高可用性。但是哨兵无法对从节点进行自动故障转移,在读写分离场景下,从节点故障会导致读服务不可用,这就需要对从节点做额外的监控、切换操作。另外,哨兵仍然没有解决写操作无法负载均衡、存储能力受到单机限制的问题。如需进一步提升性能与稳定性,需要考虑使用 Redis Cluster 模式,这个我们下回分享,敬请鉴赏。

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词