redis 哨兵模式原理和搭建

哨兵模式:
哨兵(sentinel),用于对主从结构中的每一台服务器进行监控,当主节点出现故障后通过投票机制来挑选新的主节点,并且将所有的从节点连接到新的主节点上。(可以说是主从架构的智能化 哈)
哨兵需要做的事情如下:
监控:监控主从节点运行情况。
通知:当监控节点出现故障,哨兵之间进行通讯。
自动故障转移:当监控到主节点宕机后,断开与宕机主节点连接的所有从节点,然后在从节点中选取一个作为主节点,将其他的从节点连接到这个最新的主节点。最后通知客户端最新的服务器地址。
哨兵的节点最少是三台服务器,必须是单数(投票防止平票的情况)哨兵自己的通信底层都是用发布订阅的方式,  我们程序连接都是连接哨兵就可以了;

宕机情况:

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中的异步复制情况下的数据丢失问题也能使用这两个参数

 

 

 

 

 

 

 


 

 
 
posted @   根仔  阅读(766)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示