Redis-sentinel(哨兵模式)

作用

redis服务提供了高可用性,在不需要人为干预的情况下,能抵御某些redis服务的失效,并自动修复。

除了redis集群的自动修复功能外,Redis Sentinel同时提供了一些其他的功能,例如:监控(主从个数等)、通知(通过api的方式通知某些失效的信息)、并为client提供(master)配置信息(类似于dns的作用)。

Sentinel本身是一套分布式系统

Sentinel的主要功能是通过redis的多副本的方式,保证在有instance失效的情况下,整个redis集群的可用性。但如果Sentinel只有一个instance,则它本身就会成为单点,因此Sentinel通常也是由多instance组合而成的。

Sentinel它是这样工作的:

  • 当多数的Sentinel共同认为redis master失效后,才会触发自动修复,避免了因个别Sentinel的意见而反复触发修复功能;
  • 当少数Sentinel instance失效后,整个Sentinel集群仍能发挥作用;

运行Sentinel的两种方式

redis-sentinel /path/to/sentinel.conf
redis-server /path/to/sentinel.conf –sentinel

sentinel.conf是其配置文件,每当redis集群发生变化时,配置文件会被Sentinel服务所改写,因此该配置文件实时记录了redis集群当前状态。如果Sentinel被重启,它也可以通过该配置文件了解到redis集群的当前状态,并和其它Sentinel服务共同提供服务。

Sentinel部署

通常至少需要三个Sentinel服务才能保证高可用;

每个Sentinel部署时需要考虑其失效独立,避免因同一台物理机down掉引起所有Sentinel服务失效;

即使部署了Sentinel服务,仍不能保证所有写入redis的数据100%不丢失。因为redis拷贝是异步进行的,因此即使client收到redis master写成功的回复,一旦master挂掉,数据仍然会丢失。不过有一些配置方式可以缩短写丢失的窗口;

Client需要Sentinel支持获取当前的masterreplica

一定要在测试环境上完整测试通过后再上线;

Sentinel初始配置

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1

sentinel monitor resque 192.168.1.3 6380 4
sentinel down-after-milliseconds resque 10000
sentinel failover-timeout resque 180000
sentinel parallel-syncs resque 5

上面的配置表示Sentinel集群同时监控了两个redis集群,分别起名为mymaster和resque。Mymaster master初始地址为127.0.0.1:6379,resque初始地址为192.168.1.3:6380。跟在port后面的数字为quorum,它表示至少有多少个Sentinel服务认为master失效后才能发起自动修复过程。除此以外还需要Sentinel的大多数服务均同意后才能进行选主,以及后续的修复操作。

down-after-milliseconds表示多长时间redis服务不回复,则被认为其失效,单位是ms;

parallel-syncs表示并行同步的个数,虽然replica在同步时仍能提供服务,但当它加载时仍会有一段时间无法提供服务,因此如果该数字比较大,可能造成同时有多个replica不能提供服务。

Redis失效

Redis失效分为两种情况。一是redis服务down掉,外界所有的信息均无法接收和处理;二是redis服务的网络出现的割裂,一部分外界的请求接收不到,但同时可能能接受另一部分的请求(脑裂)。

处理第一种情况相对简单,因为肯定所有的Sentinel服务和client均认为该redis已经down掉了,即使和它处于同一物理机的情况。这时如果它作为集群的master,将会进行自动修复处理。

处理第二种情况就要复杂一些,因为可能会有部分Sentinel和client仍能连接上该redis,这样client就有可能继续会往该redis写数据。即使这是该redis已经被其它多数的Sentinel认为是下线了也一样。因此丢失写数据的情况无法完全避免,但是仍有一些补救措施可以降低损失。比如在redis.conf文件中添加以下内容:

min-replicas-to-write 1 – 至少要拷贝给一个replica,否则停止写

min-replicas-max-lag 10 – 拷贝的lag为10s

同样因为redis的异步拷贝处理,这10s内的写会被丢失掉。

虽然增加了这层保护,但是在某些情况下对于redis集群的高可用是有影响的,比如其它的replica都down掉时,这时会因为不能拷贝的情况出现整个redis集群不可用。

失效自动修复的过程

  • 某一个集群的master失效;
  • 所有的Sentinel判定master是否失效,如果多于设置的quorum数目,则由发现失效的Sentinel服务提成自动修复的申请;
  • 申请需要经过多数的Sentinel服务同一,并通过选主的过程,由其中一个Sentinel服务开始执行操作;
  • Sentinel服务让其中一个replica升级为master,剩余的replica将从新的master中拷贝数据;
  • Client连接原先的master出现错误后,它会咨询Sentinel获取新masteripport
  • 原先master恢复后,会继续被添加进集群中,成为replica

如何发现新的Sentinel

通过Sentinelredis之间的交互自动感知到别的Sentinel。

一个简单的部署实例

启动一个redis master和一个redis replica服务,然后启动三个Sentinel服务对redis集群进行监控

启动redis集群

Master的端口为6379, replica的端口为6380

redis-server --port 6379
redis-server --port 6380

建立主从关系

redis-cli -h localhost -p 6380
localhost:6380> slaveof 127.0.0.1 6379
OK

这时直接向redis replica写数据就会被拒绝

启动Sentinel服务群

服务端口分别为5000,5003,5002

Sentinel.conf文件的内容如下(除了端口以外,其它的保持一致)

port 5000
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1

启动第一个sentinel服务

redis-sentinel sentinel.conf

在打印的日志中会出现如下信息:

2542:X 11 Feb 2022 18:02:42.894 # Sentinel ID is 8c70976eb0da5bef2004f5cbf63bfb2f8cf744e2
2542:X 11 Feb 2022 18:02:42.894 # +monitor master mymaster 127.0.0.1 6379 quorum 2
2542:X 11 Feb 2022 18:02:42.895 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379

从中我们可以看到sentinel服务已经获取到redis集群master和replica的地址

启动第二个sentinel服务

在打印的日志中会出现如下信息:

2638:X 11 Feb 2022 18:06:52.513 # Sentinel ID is c661286538934b5b49272e42ac0e050cbdb435c0
2638:X 11 Feb 2022 18:06:52.513 # +monitor master mymaster 127.0.0.1 6379 quorum 2
2638:X 11 Feb 2022 18:06:52.514 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
2638:X 11 Feb 2022 18:06:54.271 * +sentinel sentinel 8c70976eb0da5bef2004f5cbf63bfb2f8cf744e2 127.0.0.1 5000 @ mymaster 127.0.0.1 6379

除了第一个sentinel服务打印的信息以外,它同时识别到了另一个sentinel服务(127.0.0.1 5000)同样在监控该redis集群,因此会加入第一个sentinel服务组成一个sentinel集群

启动第三个sentinel服务

在打印的日志中会出现如下信息:

2689:X 11 Feb 2022 18:10:02.550 # Sentinel ID is 7c1330c23080550e9b669a2300e9800f2adbe4e7
2689:X 11 Feb 2022 18:10:02.551 # +monitor master mymaster 127.0.0.1 6379 quorum 2
2689:X 11 Feb 2022 18:10:02.551 * +slave slave 127.0.0.1:6380 127.0.0.1 6380 @ mymaster 127.0.0.1 6379
2689:X 11 Feb 2022 18:10:03.490 * +sentinel sentinel 8c70976eb0da5bef2004f5cbf63bfb2f8cf744e2 127.0.0.1 5000 @ mymaster 127.0.0.1 6379
2689:X 11 Feb 2022 18:10:03.979 * +sentinel sentinel c661286538934b5b49272e42ac0e050cbdb435c0 127.0.0.1 5003 @ mymaster 127.0.0.1 6379

它自动识别到另外两个sentinel服务(127.0.0.1 5000,127.0.0.1 5003)

通过sentinel服务获取master的相关信息

redis-cli -p 5000
127.0.0.1:5000> sentinel master mymaster
 1) "name"
 2) "mymaster"
 3) "ip"
 4) "127.0.0.1"
 5) "port"
 6) "6379"
 7) "runid"
 8) "070809ac08f5d12572a0d00009dfa6afc1e74678"
 9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "545"
19) "last-ping-reply"
20) "545"
21) "down-after-milliseconds"
22) "5000"
23) "info-refresh"
24) "5527"
25) "role-reported"
26) "master"
27) "role-reported-time"
28) "658057"
29) "config-epoch"
30) "0"
31) "num-slaves"
32) "1"
33) "num-other-sentinels"
34) "2"
35) "quorum"
36) "2"
37) "failover-timeout"
38) "60000"
39) "parallel-syncs"
40) "1"

通过sentinel服务获取replica的相关信息

127.0.0.1:5000> SENTINEL replicas mymaster
1)  1) "name"
    2) "127.0.0.1:6380"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "6380"
    7) "runid"
    8) "960cd7e7736862046149ca42b9c3bcb89a6a8fc4"
    9) "flags"
   10) "slave"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "351"
   19) "last-ping-reply"
   20) "351"
   21) "down-after-milliseconds"
   22) "5000"
   23) "info-refresh"
   24) "1838"
   25) "role-reported"
   26) "slave"
   27) "role-reported-time"
   28) "925434"
   29) "master-link-down-time"
   30) "0"
   31) "master-link-status"
   32) "ok"
   33) "master-host"
   34) "127.0.0.1"
   35) "master-port"
   36) "6379"
   37) "slave-priority"
   38) "100"
   39) "slave-repl-offset"
   40) "136107"

通过sentinel服务获取其它sentinel的相关信息

127.0.0.1:5000> SENTINEL sentinels mymaster
1)  1) "name"
    2) "7c1330c23080550e9b669a2300e9800f2adbe4e7"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "5002"
    7) "runid"
    8) "7c1330c23080550e9b669a2300e9800f2adbe4e7"
    9) "flags"
   10) "sentinel"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "288"
   19) "last-ping-reply"
   20) "288"
   21) "down-after-milliseconds"
   22) "5000"
   23) "last-hello-message"
   24) "1237"
   25) "voted-leader"
   26) "?"
   27) "voted-leader-epoch"
   28) "0"
2)  1) "name"
    2) "c661286538934b5b49272e42ac0e050cbdb435c0"
    3) "ip"
    4) "127.0.0.1"
    5) "port"
    6) "5003"
    7) "runid"
    8) "c661286538934b5b49272e42ac0e050cbdb435c0"
    9) "flags"
   10) "sentinel"
   11) "link-pending-commands"
   12) "0"
   13) "link-refcount"
   14) "1"
   15) "last-ping-sent"
   16) "0"
   17) "last-ok-ping-reply"
   18) "288"
   19) "last-ping-reply"
   20) "288"
   21) "down-after-milliseconds"
   22) "5000"
   23) "last-hello-message"
   24) "710"
   25) "voted-leader"
   26) "?"
   27) "voted-leader-epoch"
   28) "0"

参考文献

Redis Sentinel Documentation – Redis

你可能感兴趣的:(架构,redis,缓存,数据库)