哨兵结构

  1. 哨兵的作用如下:
    • 监控:Sentinel 会不断检查您的master和slave是否按预期工作。
    • 自动故障恢复:如果master故障,Sentinel会将一个slave提升为master。当故障实例恢复后也以新的master为主。
    • 通知:Sentinel充当Redis客户端的服务发现来源,当集群发生故障转移时,会将最新信息推送给Redis的客户端。

监控集群原理

  1. Sentinel基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令:
    • 主观下线:如果某sentinel节点发现某实例未在规定时间响应,则认为该实例主观下线
    • 客观下线:若超过指定数量(quorum)的sentinel都认为该实例主观下线,则该实例客观下线。quorum值最好超过Sentinel实例数量的一半。

集群故障恢复

  1. 一旦发现master故障,sentinel需要在salve中选择一个作为新的master,选择依据是这样的:
    • 首先会判断slave节点与master节点断开时间长短,如果超过指定值(down-after-milliseconds * 10)则会排除该slave节点。
    • 然后判断slave节点的slave-priority值,越小优先级越高,如果是0则永不参与选举。
    • 如果slave-prority一样,则判断slave节点的offset值,越大说明数据越新,优先级越高。
    • 最后是判断slave节点的运行id大小,越小优先级越高。
  2. 当选出一个新的master后,切换流程:
    • sentinel给备选的slave1节点发送slaveof no one命令,让该节点成为master。
    • sentinel给所有其它slave发送slaveof 192.168.150.101 7002命令,让这些slave成为新master的从节点,开始从新的master上同步数据。
    • 最后,sentinel将故障节点标记为slave,当故障节点恢复后会自动成为新的master的slave节点。

总结

  1. Sentinel的三个作用是:监控、故障转移、通知。
  2. Sentinel判断一个redis实例是否健康:
    • 每隔1秒发送一次ping命令,如果超过一定时间没有相向则认为是主观下线。
    • 如果大多数sentinel都认为实例主观下线,则判定服务下线。
  3. 故障转移步骤:
    • 首先选定一个slave作为新的master,执行slaveof no one。
    • 然后让所有节点都执行slaveof 新master。
    • 修改故障节点配置,添加slaveof 新master。

搭建

  1. 以前一篇主从搭建为基础。
  2. 配置 sentinel.conf 文件,github下载对应版本。
  3. 修改以下内容。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# sentinel1.conf

# docker对外开放的端口
port 37376

requirepass 12345678

# 服务后台运行
# 因为使用docker启动时使用了-d参数,所以需要设置为no, 非docker设置为yes
daemonize no

dir /tmp

# 这里配置的是监控的redis的地址,mymaster为默认的主节点名字
# 后面的2为客观掉线的票数,一般为集群数除二
#   mymasterr:主节点名称,自定义,任意写
#   172.30.1.2 7001:主节点的ip和端口
#   2:选举master时的quorum值
sentinel monitor mymaster 172.30.1.2 7001 2

sentinel auth-pass mymaster 12345678

# # 超过30秒master还没有连接上,则认为master已经停止,30000ms,默认30秒
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1

# 故障转移超时时间 默认3分钟
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# sentinel2.conf

# docker对外开放的端口
port 37377

requirepass 12345678

# 服务后台运行
# 因为使用docker启动时使用了-d参数,所以需要设置为no, 非docker设置为yes
daemonize no

dir /tmp

# 这里配置的是监控的redis的地址,mymaster为默认的主节点名字
# 后面的2为客观掉线的票数,一般为集群数除二
#   mymasterr:主节点名称,自定义,任意写
#   172.30.1.2 7001:主节点的ip和端口
#   2:选举master时的quorum值
sentinel monitor mymaster 172.30.1.2 7001 2

sentinel auth-pass mymaster 12345678

# # 超过30秒master还没有连接上,则认为master已经停止,30000ms,默认30秒
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1

# 故障转移超时时间 默认3分钟
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# sentinel3.conf

# docker对外开放的端口
port 37378

requirepass 12345678

# 服务后台运行
# 因为使用docker启动时使用了-d参数,所以需要设置为no, 非docker设置为yes
daemonize no

dir /tmp

# 这里配置的是监控的redis的地址,mymaster为默认的主节点名字
# 后面的2为客观掉线的票数,一般为集群数除二
#   mymasterr:主节点名称,自定义,任意写
#   172.30.1.2 7001:主节点的ip和端口
#   2:选举master时的quorum值
sentinel monitor mymaster 172.30.1.2 7001 2

sentinel auth-pass mymaster 12345678

# # 超过30秒master还没有连接上,则认为master已经停止,30000ms,默认30秒
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1

# 故障转移超时时间 默认3分钟
sentinel failover-timeout mymaster 180000
sentinel deny-scripts-reconfig yes

docker-compose.yml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
version: '3'
services:
  redis-sentinel1:
    image: redis:6.2.3
    container_name: redis-sentinel1
    restart: always
    ports:
      - 37376:37376
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - /home/redis/config/sentinel1.conf:/usr/local/etc/redis/sentinel.conf
    #   - ./data/redis-sentinel:/data
    sysctls:
      # 必要的内核参数
      net.core.somaxconn: '511'

  redis-sentinel2:
    image: redis:6.2.3
    container_name: redis-sentinel2
    restart: always
    ports:
      - 37377:37377
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - /home/redis/config/sentinel2.conf:/usr/local/etc/redis/sentinel.conf
    #   - ./data/redis-sentinel:/data
    sysctls:
      # 必要的内核参数
      net.core.somaxconn: '511'

  redis-sentinel3:
    image: redis:6.2.3
    container_name: redis-sentinel3
    restart: always
    ports:
      - 37378:37378
    command: redis-sentinel /usr/local/etc/redis/sentinel.conf
    volumes:
      - /home/redis/config/sentinel3.conf:/usr/local/etc/redis/sentinel.conf
    #   - ./data/redis-sentinel:/data
    sysctls:
      # 必要的内核参数
      net.core.somaxconn: '511'
$ docker-compose -f docker-sentinel.yml up -d

参考

  1. https://www.cnblogs.com/coolxin1024/p/17182557.html