redis 哨兵模式原理和搭建

宕机情况:
1.主观宕机:单独哨兵认为你宕机了,发现了故障。
2.客观宕机:半数哨兵认为主节点宕机,发现了故障。
选举主节点的原则:
1.健康度。。从节点响应的时间
2.完整性。根据我们从节点备份的完整性,根据数据备份偏移量
3.稳定性。根据启动时间周期,心跳检测
4.如果上面三个条件都相等,则根据我们节点启动时分配的run id来,如果runid越小,则最有可能选择为我们主节点
数据丢失的问题是指:当客户端已经把数据写到主节点上了 ,突然主节点挂了,但主节点的数据是还没有同步到某个从节点,从节点就替换了主节点成为主节点 这个时候的数据不一致才叫数据丢失问题
先用原本设置好的文件配置主从模式:
1.在服务其中创建目录
mkdir /usr/local/etc/redis/sentinel/sentinel -p
cd /usr/local/etc/redis/sentinel/sentinel
2.把文件夹sentinel,server 拉到这个目录下
切换到server目录下
我们配置了三个文件 :docker-compose.yml redis-master.conf redis-slave1.conf redis-slave2.conf 分别配置内容如下
version: '3' services: # 主节点的容器 redis-server-master: image: redis container_name: redis-server-master restart: always # 为了规避Docker中端口映射可能带来的问题 # 这里选择使用host网络 network_mode: host # 指定时区,保证容器内时间正确 environment: TZ: "Asia/Shanghai" volumes: # 映射配置文件和数据目录 - ./redis-master.conf:/usr/local/etc/redis/redis.conf - ./data/redis-master:/data command: ["redis-server", "/usr/local/etc/redis/redis.conf"] # 从节点1的容器 redis-server-slave-1: image: redis container_name: redis-server-slave-1 restart: always network_mode: host depends_on: - redis-server-master environment: TZ: "Asia/Shanghai" volumes: - ./redis-slave1.conf:/usr/local/etc/redis/redis.conf - ./data/redis-slave-1:/data command: ["redis-server", "/usr/local/etc/redis/redis.conf"] # 从节点2的容器 redis-server-slave-2: image: redis container_name: redis-server-slave-2 restart: always network_mode: host depends_on: - redis-server-master environment: TZ: "Asia/Shanghai" volumes: - ./redis-slave2.conf:/usr/local/etc/redis/redis.conf - ./data/redis-slave-2:/data command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
# 监听端口 port 6379 # 启动时不打印logo # 这个不重要,想看logo就打开它 always-show-logo no # 设定密码认证 requirepass 123456 # 禁用KEYS命令 # 一方面 KEYS * 命令可以列出所有的键,会影响数据安全 # 另一方面 KEYS 命令会阻塞数据库,在数据库中存储了大量数据时,该命令会消耗很长时间 # 期间对Redis的访问也会被阻塞,而当锁释放的一瞬间,大量请求涌入Redis,会造成Redis直接崩溃 rename-command KEYS ""
# bind 127.0.0.1 # 监听端口 port 6380 always-show-logo no requirepass 123456 rename-command KEYS "" slaveof 127.0.0.1 6379 # 设定连接主节点所使用的密码 masterauth "123456"
# 监听端口 port 6381 always-show-logo no # 设定密码认证 requirepass 123456 rename-command KEYS "" slaveof 127.0.0.1 6379 # 设定连接主节点所使用的密码 masterauth "123456"
3 命令启动 docker-compose up -d
如何搭建哨兵模式:
1.在服务其中创建目录
mkdir /usr/local/etc/redis/sentinel/sentinel -p
cd /usr/local/etc/redis/sentinel/sentinel
2.把文件夹sentinel,server 拉到这个目录下
切换到sentinel目录下下我们配置了三个文件 :docker-compose.yml redis-sentinel-1.conf redis-sentinel-2.conf redis-sentinel-3.conf 分别配置内容如下
version: '3' services: redis-sentinel-1: image: redis container_name: redis-sentinel-1 restart: always # 为了规避Docker中端口映射可能带来的问题 # 这里选择使用host网络 network_mode: host volumes: - ./redis-sentinel-1.conf:/usr/local/etc/redis/redis-sentinel.conf # 指定时区,保证容器内时间正确 environment: TZ: "Asia/Shanghai" command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"] redis-sentinel-2: image: redis container_name: redis-sentinel-2 restart: always network_mode: host volumes: - ./redis-sentinel-2.conf:/usr/local/etc/redis/redis-sentinel.conf environment: TZ: "Asia/Shanghai" command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"] redis-sentinel-3: image: redis container_name: redis-sentinel-3 restart: always network_mode: host volumes: - ./redis-sentinel-3.conf:/usr/local/etc/redis/redis-sentinel.conf environment: TZ: "Asia/Shanghai" command: ["redis-sentinel", "/usr/local/etc/redis/redis-sentinel.conf"]
port 26379 requirepass 123456 sentinel monitor local-master 127.0.0.1 6379 2 sentinel auth-pass local-master 123456 # master在连续多长时间无法响应PING指令后,就会主观判定节点下线,默认是30秒 # 格式:sentinel down-after-milliseconds <master-name> <milliseconds> sentinel down-after-milliseconds local-master 30000
port 26380 requirepass 123456 sentinel monitor local-master 127.0.0.1 6379 2 sentinel auth-pass local-master 123456 # master在连续多长时间无法响应PING指令后,就会主观判定节点下线,默认是30秒 # 格式:sentinel down-after-milliseconds <master-name> <milliseconds> sentinel down-after-milliseconds local-master 30000
port 26381 requirepass 123456 sentinel monitor local-master 127.0.0.1 6379 2 sentinel auth-pass local-master 123456 # master在连续多长时间无法响应PING指令后,就会主观判定节点下线,默认是30秒 # 格式:sentinel down-after-milliseconds <master-name> <milliseconds> sentinel down-after-milliseconds local-master 30000
3 命令启动 docker-compose up -d
查看情况 docker ps -a
查看到哨兵的主从搭建的容器已经成功
进入哨兵的主节点:docker exec -it redis-serveer-master /bin/bash =====> redis-cli -a 123456 -h 192.168.1.211 -p 6380 ====> info replication ====> set name gengen =====> get name 测试一下 其他的从节点也进去 get name 看看
让后把主节点的redis 停掉 ====》 docker stop redis-server-master
4 如果主节点回复了呢 ====》docker start redis-server-master 会自动回复原来的主从关系
哨兵或者主从里面的数据问题:
1.脑裂问题
什么是redis的集群脑裂?
redis的集群脑裂是指因为网络问题,导致redis master节点跟redis slave节点和sentinel集群处于不同的网络分区,此时因为sentinel集群无法感知到master的存在,所以将slave节点提升为master节点。此时存在两个不同的master节点,就像一个大脑分裂成了两个。
集群脑裂问题中,如果客户端还在基于原来的master节点继续写入数据,那么新的master节点将无法同步这些数据,当网络问题解决之后,sentinel集群将原先的master节点降为slave节点,此时再从新的master中同步数据,将会造成大量的数据丢失。
出现了主节点和哨兵之间网络原因,而且有多数以上的哨兵认为主节点宕机,则再从会从节点现在一个主,这个时候客户端代码还是可以连接到之前的主节点的,可以写数据,此时哨兵选举了新的主节点,然后之前的主网络恢复了,然后之前的主节点备份现在的主节点数据,造成数据不完整。。。
2.异步复制数据丢失问题
因为是异步复制数据,如果主节点和从节点直接数据复制太慢,在这之间主节点宕机,而且是真的宕机,这个时候从节点替换主节点,丢失了数据。。
哨兵--不管怎么样的配置都没有办法保证数据百分之白不丢失,只能尽可能少量丢数据
怎么解决上面这来个问题呢?
需要改配置文件:
1.至少有几个从节点。配置=0,代表的是,当主节点和从节点之间互通的时候,发现从节点小于一个的时候,则从节点不会再继续给客户端提供服务。。 解决脑裂问题。。
2.偏移量配置。。。主节点和从节点数据之前偏移量只差,如果偏移量只差比配置小,则主节点也不会提供服务。。
解决方案
redis的配置文件中,存在两个参数
min-slaves-to-write 3 min-slaves-max-lag 10
第一个参数表示连接到master的最少slave数量
第二个参数表示slave连接到master的最大延迟时间
按照上面的配置,要求至少3个slave节点,且数据复制和同步的延迟不能超过10秒,否则的话master就会拒绝写请求,配置了这两个参数之后,如果发生集群脑裂,原先的master节点接收到客户端的写入请求会拒绝,就可以减少数据同步之后的数据丢失。
注意:较新版本的redis.conf文件中的参数变成了
min-replicas-to-write 3 min-replicas-max-lag 10
redis中的异步复制情况下的数据丢失问题也能使用这两个参数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!