哨兵(sentinel)的主要作用为:当master节点发生故障时,众多slave节点中的一个可晋升为新的master节点来提供写服务,其余的slave节点仍然提供读服务,这种机制也别称为故障转移(failover)。主从复制+哨兵的架构模式如下所示:
Redis哨兵架构 - 图1

配置

下面通过docker-compose演示如何在主从架构的基础上启用哨兵机制。修改docker-compose.yml文件内容,在volume中多加一个数据卷的映射,对应的配置文件为哨兵所需的.conf配置文件。

  1. version: '3.1'
  2. services:
  3. redis1:
  4. image: daocloud.io/library/redis:5.0.7
  5. restart: always
  6. container_name: redis1
  7. environment:
  8. - TZ=Asia/Shanghai
  9. ports:
  10. - 7001:6379
  11. volumes:
  12. - ./conf/redis1.conf:/usr/local/redis/redis.conf
  13. - ./conf/sentinel1.conf:/data/sentinel.conf
  14. command: ["redis-server", "/usr/local/redis/redis.conf"]
  15. redis2:
  16. image: daocloud.io/library/redis:5.0.7
  17. restart: always
  18. container_name: redis2
  19. environment:
  20. - TZ=Asia/Shanghai
  21. ports:
  22. - 7002:6379
  23. volumes:
  24. - ./conf/redis2.conf:/usr/local/redis/redis.conf
  25. - ./conf/sentinel2.conf:/data/sentinel.conf
  26. links:
  27. - redis1:master
  28. command: ["redis-server", "/usr/local/redis/redis.conf"]
  29. redis3:
  30. image: daocloud.io/library/redis:5.0.7
  31. restart: always
  32. container_name: redis3
  33. environment:
  34. - TZ=Asia/Shanghai
  35. ports:
  36. - 7003:6379
  37. volumes:
  38. - ./conf/redis3.conf:/usr/local/redis/redis.conf
  39. - ./conf/sentinel3.conf:/data/sentinel.conf
  40. links:
  41. - redis1:master
  42. command: ["redis-server", "/usr/local/redis/redis.conf"]

并且在宿主机的conf目录下新建三个.conf配置文件。其中master对应的sentinel1.conf文件内容为:

  1. # 哨兵需要后台启动
  2. daemonize yes
  3. # 指定master节点的ip和端口
  4. sentinel monitor master 127.0.0.1 6379 2
  5. # 哨兵每隔多久监听一次Redis架构
  6. sentinel down-after-milliseconds master 10000

在slave节点的哨兵配置文件中填写如下内容:

  1. # 哨兵需要后台启动
  2. daemonize yes
  3. # 指定master节点的ip和端口
  4. sentinel monitor master master 6379 2
  5. # 哨兵每隔多久监听一次Redis架构
  6. sentinel down-after-milliseconds master 10000

然后使用docker-compose up -d启动容器,可以看到此时redis都已经正常启动,但是哨兵并没有启动。
Redis哨兵架构 - 图2

接着需要分别进入到三个Redis容器内部,使用redis-sentinel sentinel1.confredis-sentinel sentinel2.confredis-sentinel sentinel2.conf分别启动哨兵。退出容器后,再次查看宿主机的sentinel1.conf文件可以看到如下内容:
Redis哨兵架构 - 图3

至此,带有哨兵机制的主从架构就启动完毕。

原理

哨兵具有如下的功能:

  • 监控:哨兵会不断的检查master节点和slave节点是否正常运作
  • 自动故障转移:当哨兵发现master节点无法正常工作,它会将对应的slave节点中的一个晋升为master节点。即使出错的master节点后续恢复正常,它也只能作为新master节点的slave
  • 配置提供者:客户端初始化时,通过哨兵来获取当前Redis服务的master节点配置
  • 通知:哨兵可以将故障转移的结果发送给客户端

其中,当master节点发生故障时,新的master节点的选择原则如下:

  1. 在失效主服务器属下的从服务器当中, 那些被标记为主观下线、已断线、或者最后一次回复 PING 命令的时间大于五秒钟的从服务器都会被 淘汰
  2. 在失效主服务器属下的从服务器当中, 那些与失效主服务器连接断开的时长超过 down-after 选项指定的时长十倍的从服务器都会被 淘汰
  3. 经历了以上两轮淘汰之后 剩下来的从服务器中, 我们选出 复制偏移量(replication offset)最大 的那个 从服务器 作为新的主服务器;如果复制偏移量不可用,或者从服务器的复制偏移量相同,那么 带有最小运行 ID 的那个从服务器成为新的主服务器

那么,哨兵是如何感知到master节点出现故障了呢? 哨兵节点会定期的向master节点发送心跳包判断其是否存活,称为PING。当某个哨兵发现master发生了故障,它将其标记为主观不可用状态,然后将其发送给其他的哨兵节点。如果确认master故障的哨兵节点个数超过了设置的阈值,则认为该master客观不可用,进行故障转移的流程。