为redis服务提供了高可用性,在不需要人为干预的情况下,能抵御某些redis服务的失效,并自动修复。
除了redis集群的自动修复功能外,Redis Sentinel同时提供了一些其他的功能,例如:监控(主从个数等)、通知(通过api的方式通知某些失效的信息)、并为client提供(master)配置信息(类似于dns的作用)。
Sentinel的主要功能是通过redis的多副本的方式,保证在有instance失效的情况下,整个redis集群的可用性。但如果Sentinel只有一个instance,则它本身就会成为单点,因此Sentinel通常也是由多instance组合而成的。
Sentinel它是这样工作的:
redis-sentinel /path/to/sentinel.conf
redis-server /path/to/sentinel.conf –sentinel
sentinel.conf是其配置文件,每当redis集群发生变化时,配置文件会被Sentinel服务所改写,因此该配置文件实时记录了redis集群当前状态。如果Sentinel被重启,它也可以通过该配置文件了解到redis集群的当前状态,并和其它Sentinel服务共同提供服务。
通常至少需要三个Sentinel服务才能保证高可用;
每个Sentinel部署时需要考虑其失效独立,避免因同一台物理机down掉引起所有Sentinel服务失效;
即使部署了Sentinel服务,仍不能保证所有写入redis的数据100%不丢失。因为redis拷贝是异步进行的,因此即使client收到redis master写成功的回复,一旦master挂掉,数据仍然会丢失。不过有一些配置方式可以缩短写丢失的窗口;
Client需要Sentinel支持获取当前的master和replica;
一定要在测试环境上完整测试通过后再上线;
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服务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集群不可用。
通过Sentinel和redis之间的交互自动感知到别的Sentinel。
启动一个redis master和一个redis replica服务,然后启动三个Sentinel服务对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写数据就会被拒绝
服务端口分别为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
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的地址
在打印的日志中会出现如下信息:
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集群
在打印的日志中会出现如下信息:
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)
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"
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"
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