redis 哨兵模式

一、前言

redis 主从复制模式下, 一旦主节点出现故障, 不能提供服务的时候, 就需要人工进行主从切换. 这是十分不靠谱的, 毕竟谁也不知道主节点什么时候出现故障, 这样就无法第一时间恢复服务. 所以 redis 从 2.8 版本开始提供了 哨兵(Redis Sentinel) 模式, 可以通过自动化手段来解决主节点出现故障的问题.进而实现故障转移。

二、主从复制的问题

 redis 主从复制是将主节点的数据同步给从节点, 这样从节点就拥有主节点的所有数据, 这样客户端就可以从从节点这边来读取数据, 来分担主节点所要承受的并发量. 但是主从复制也有一些问题:

问题一:主节点发生故障的时候, 这时整个 redis 服务就失去了写入数据的功能, 这时就需要程序员手动干预来将从节点切换成主节点.
问题二:主从复制可以将读的并发量分担给从节点, 但是写压力/存储压力是无法被分担的, 还是受到单机的限制.
其中第一个问题就是哨兵模式主要解决的问题, 而第二个问题是 redis 集群模式解决的问题, 本章主要讨论第一个问题.

三、哨兵的原理&故障转移过程

(1)定时任务:每个哨兵节点维护了3个定时任务。定时任务的功能分别如下:通过向主从节点发送info命令获取最新的主从结构;通过发布订阅功能获取其他哨兵节点的信息;通过向其他节点发送ping命令进行心跳检测,判断是否下线。

(2)主观下线:在心跳检测的定时任务中,如果其他节点超过一定时间没有回复,哨兵节点就会将其进行主观下线。顾名思义,主观下线的意思是一个哨兵节点“主观地”判断下线;与主观下线相对应的是客观下线。

(3)客观下线:哨兵节点在对主节点进行主观下线后,会通过sentinel is-master-down-by-addr命令询问其他哨兵节点该主节点的状态;如果判断主节点下线的哨兵数量达到一定数值,则对该主节点进行客观下线。

(4)选举领导者哨兵节点:当主节点被判断客观下线以后,各个哨兵节点会进行协商,选举出一个领导者哨兵节点,并由该领导者节点对其进行故障转移操作。

监视该主节点的所有哨兵都有可能被选为领导者,选举使用的算法是Raft算法;Raft算法的基本思路是先到先得:即在一轮选举中,哨兵A向B发送成为领导者的申请,如果B没有同意过其他哨兵,则会同意A成为领导者。选举的具体过程这里不做详细描述,一般来说,哨兵选择的过程很快,谁先完成客观下线,一般就能成为领导者。

(5)故障转移:选举出的领导者哨兵,开始进行故障转移操作,该操作大体可以分为3个步骤:

  • 在从节点中选择新的主节点:选择的原则是,首先过滤掉不健康的从节点;然后选择优先级最高的从节点(由slave-priority指定);如果优先级无法区分,则选择复制偏移量最大的从节点;如果仍无法区分,则选择runid最小的从节点。
  • 更新主从状态:通过slaveof no one命令,让选出来的从节点成为主节点;并通过slaveof命令让其他节点成为其从节点。
  • 将已经下线的主节点(即6379)设置为新的主节点的从节点,当6379重新上线后,它会成为新的主节点的从节点。
  • 通知:哨兵可以将故障转移的结果发送给客户端

四、实践案例:

用docker来模拟主从及哨兵模式:

1、搭建redis主从服务 redis.yml:

version: '2.0'

services:
  redis-master:
    image: redis
    container_name: redis-master
    ports:
      - "6380:6379"
    networks:
      - redis-net
    command: redis-server --port 6379

  redis-slave-1:
    image: redis
    container_name: redis-slave-1
    ports:
      - "6381:6379"
    networks:
      - redis-net
    command: redis-server --slaveof redis-master 6379 --port 6379

  redis-slave-2:
    image: redis
    container_name: redis-slave-2
    ports:
      - "6382:6379"
    networks:
      - redis-net
    command: redis-server --slaveof redis-master 6379 --port 6379

networks:
  redis-net:
    external: true

2、搭建redis哨兵 sentinel.yml:

哨兵个数为大于等于3等奇数个。

version: '2.0'

services:
  redis-sentinel-1:
    image: redis:5.0.9
    container_name: redis-sentinel-1
    restart: always
    ports:
      - "26379:26379"
    networks:
      - redis-net
    volumes:
      - ./sentinel.conf:/etc/redis/sentinel.conf
    command: redis-sentinel /etc/redis/sentinel.conf

  redis-sentinel-2:
    image: redis:5.0.9
    container_name: redis-sentinel-2
    ports:
      - "26380:26379"
    networks:
      - redis-net
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel1.conf:/etc/redis/sentinel.conf

  redis-sentinel-3:
    image: redis:5.0.9
    container_name: redis-sentinel-3
    ports:
      - "26381:26379"
    networks:
      - redis-net
    command: redis-sentinel /etc/redis/sentinel.conf
    volumes:
      - ./sentinel2.conf:/etc/redis/sentinel.conf

networks:
  redis-net:
    external: true

三个sentinel.conf文件一样,如下:

bind 0.0.0.0
port 26379
sentinel monitor mymaster redis-master 6379 2

它告诉 Sentinel 监视名为 mymaster 的主节点,地址为 redis-master,该主节点监听在 6379 端口上。最后一个参数 2 表示在 Sentinel 发现主节点失效后,至少需要 2 个 Sentinel 同意进行故障转移,才会执行故障转移操作。

启动服务:

docker network create redis-net  先创建一个外部网络环境

docker-compose -f redis.yml up    启动reids主从服务

docker-compose -f sentinel.yml up  启动哨兵服务

主从日志:

哨兵日志:

哨兵启动后,会自动修改配置文件如下:

bind 0.0.0.0           # 将 Sentinel 服务绑定到所有网络接口
port 26379              # Sentinel 服务监听的端口号
sentinel myid 5cc2477171288ff3dbaf1db764520983ca75e60c   # Sentinel 服务的唯一标识符
# Generated by CONFIG REWRITE
dir "/data"             # Sentinel 的工作目录,用于存储运行时数据
sentinel deny-scripts-reconfig yes   # 禁止 Sentinel 在运行时重新加载脚本,以增强安全性
sentinel monitor mymaster 172.28.0.4 6379 2   # 配置 Sentinel 监视名为 mymaster 的主节点,要求至少 2 个 Sentinel 同意进行故障转移,172.28.0.4是主节点容器ip
sentinel config-epoch mymaster 0   # 主节点 mymaster 的配置纪元
sentinel leader-epoch mymaster 0   # 主节点 mymaster 的领导者纪元
sentinel known-replica mymaster 172.28.0.2 6379   # 主节点 mymaster 已知的从节点列表
sentinel known-replica mymaster 172.28.0.3 6379   # 主节点 mymaster 已知的从节点列表
sentinel known-sentinel mymaster 172.28.0.7 26379 1fb0c93185eeb00e37c2b222d9dd069e433387a2   # 主节点 mymaster 已知的其他 Sentinel 节点列表
sentinel known-sentinel mymaster 172.28.0.5 26379 7b4fa92be37276cce79d770e2d7afeb5f67bf9e2   # 主节点 mymaster 已知的其他 Sentinel 节点列表
sentinel current-epoch 0   # 当前的 Sentinel 集群纪元

(以上ip都是容器内服务ip)

模拟主节点故障:

docker stop redis-master

哨兵日志:

自动修改后的哨兵配置文件:

bind 0.0.0.0
port 26379
sentinel myid 5cc2477171288ff3dbaf1db764520983ca75e60c
# Generated by CONFIG REWRITE
dir "/data"
sentinel deny-scripts-reconfig yes
sentinel monitor mymaster 172.28.0.2 6379 2  主节点由172.28.0.4切换为172.28.0.2
sentinel config-epoch mymaster 1
sentinel leader-epoch mymaster 1
sentinel known-replica mymaster 172.28.0.3 6379
sentinel known-replica mymaster 172.28.0.4 6379
sentinel known-sentinel mymaster 172.28.0.7 26379 1fb0c93185eeb00e37c2b222d9dd069e433387a2
sentinel known-sentinel mymaster 172.28.0.5 26379 7b4fa92be37276cce79d770e2d7afeb5f67bf9e2
sentinel current-epoch 1

哨兵模式需要客户端配合才能达到预期的故障转移效果,因为故障转移后,主节点ip会发生变化,客户端通常需要监听哨兵通知,做出相应动作调整连接信息。

相关推荐

  1. Redis 哨兵模式

    2024-04-08 13:40:02       28 阅读
  2. Redis哨兵模式

    2024-04-08 13:40:02       26 阅读
  3. Redis 哨兵模式

    2024-04-08 13:40:02       19 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-08 13:40:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-08 13:40:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-08 13:40:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-08 13:40:02       18 阅读

热门阅读

  1. 利用hdfs gateway挂载NFS到本地

    2024-04-08 13:40:02       10 阅读
  2. GitOps是DevOps的下一个风口吗?

    2024-04-08 13:40:02       13 阅读
  3. FDA 上市库 Mini | 药物筛选 | MCE

    2024-04-08 13:40:02       14 阅读
  4. HyperBus协议--HyperFLASH中Program Suspend 功能的理解

    2024-04-08 13:40:02       11 阅读
  5. 3.9 Python格式化字符串

    2024-04-08 13:40:02       9 阅读
  6. 蓝桥杯练习题 —— 圆的面积(python)

    2024-04-08 13:40:02       11 阅读
  7. abc348 D~F题解

    2024-04-08 13:40:02       13 阅读