Redis 哨兵集群如何实现高可用?(1)
目录
1.哨兵的介绍
2.哨兵的核心知识
3.Redis 哨兵主备切换的数据丢失问题
(1)异步复制导致的数据丢失
(2)脑裂导致的数据丢失
4.数据丢失问题的解决方案
(1)减少异步复制数据的丢失
(2)减少脑裂的数据丢失
5.sdown 和 odown 转换机制 ·sdown 是主观宕机,就一个哨兵如果自己觉得一个 master 宕机了,那么就是主观宕机。
6.哨兵集群的自动发现机制
1.哨兵的介绍
sentinel,中文名是哨兵。哨兵是 Redis 集群架构中非常重要的一个组件,主要有以下功能:
·集群监控:负责监控 Redis master 和 slave 进程是否正常工作。
·消息通知:如果某个 Redis 实例有故障,那么哨兵负责发送消息作为报警通知给管理员。
·故障转移:如果 master node 挂掉了,会自动转移到 slave node 上。
·配置中心:如果故障转移发生了,通知 client 客户端新的 master 地址。
哨兵用于实现 Redis 集群的高可用,本身也是分布式的,作为一个哨兵集群去运行,互相协同工作。
·故障转移时,判断一个 master node 是否宕机了,需要大部分的哨兵都同意才行,涉及到了分布式选举的问题。
·即使部分哨兵节点挂掉了,哨兵集群还是能正常工作的,因为如果一个作为高可用机制重要组成部分的故障转移系统本身是单点的,那就很坑爹了。
2.哨兵的核心知识
·哨兵至少需要3个实例,来保证自己的健壮性。
·哨兵+ Redis 主从的部署架构,是不保证数据零丢失的,只能保证 Redis 集群的高可用性。
·对于哨兵+Redis 主从这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练。
哨兵集群必须部署2个以上节点,如果哨兵集群仅仅部署了2个哨兵实例,quorum=1。
配置 quorum=1 ,如果 master 宕机, s1和 s2 中只要有1个哨兵认为 master 宕机了,就可以进行切换,同时 s1和 s2 会选举出一个哨兵来执行故障转移。但是同时这个时候,需要majority,也就是大多数哨兵都是运行的。
如果此时仅仅是 M1进程宕机了,哨兵 s1 正常运行,那么故障转移是 OK 的。但是如果是整个M1 和 S1 运行的机器宕机了,那么哨兵只有1个,此时就没有 majority 来允许执行故障转移,虽然另外一台机器上还有一个 R1,但是故障转移不会执行。
经典的3节点哨兵集群是这样的:
配置 quorum=2 ,如果 M1所在机器宕机了,那么三个哨兵还剩下2个,S2 和 S3 可以一致认为 master 宕机了,然后选举出一个来执行故障转移,同时3个哨兵的 majority是 2,所以还剩下的2个哨兵运行着,就可以允许执行故障转移。
3.Redis 哨兵主备切换的数据丢失问题
导致数据丢失的两种情况(主备切换的过程,可能会导致数据丢失)
(1)异步复制导致的数据丢失
因为 master->slave 的复制是异步的,所以可能有部分数据还没复制到 slave,master 就宕机了,此时这部分数据就丢失了。
(2)脑裂导致的数据丢失
脑裂,也就是说,某个 master 所在机器突然脱离了正常的网络,跟其他 slave 机器不能连接,但是实际上 master 还运行着。此时哨兵可能就会认为 master 宕机了,然后开启选举,将其他 slave 切换成了 master。这个时候,集群里就会有两个 master ,也就是所谓的脑裂。
此时虽然某个 slave 被切换成了 master,但是可能 client 还没来得及切换到新的 master,还继续向旧 master 写数据。因此旧 master 再次恢复的时候,会被作为一个 slave 挂到新的 master上去,自己的数据会清空,重新从新的 master 复制数据。而新的 master 并没有后来 client 写入的数据,因此,这部分数据也就丢失了。
4.数据丢失问题的解决方案
进行如下配置:
min-slaves-to-write 1 min-slaves-max-lag 10
表示,要求至少有1个 slave,数据复制和同步的延迟不能超过 10 秒。
如果说一旦所有的 slave,数据复制和同步的延迟都超过了 10 秒钟,那么这个时候,master 就不会再接收任何请求了。
(1)减少异步复制数据的丢失
有了 min-slaves-max-lag 这个配置,就可以确保说,一旦 slave 复制数据和 ack 延时太长就认为可能 master 宕机后损失的数据太多了,那么就拒绝写请求,”这样可以把 master 宕机时由于部分数据未同步到 slave 导致的数据丢失降低的可控范围内。
(2)减少脑裂的数据丢失
如果一个 master 出现了脑裂,跟其他 slave 丢了连接,那么上面两个配置可以确保说,如果不能继续给指定数量的 slave 发送数据,而且 slave 超过 10 秒没有给自己 ack 消息,那么就直接拒绝客户端的写请求。因此在脑裂场景下,最多就丢失10秒的数据。
5.sdown 和 odown 转换机制
·sdown 是主观宕机,就一个哨兵如果自己觉得一个 master 宕机了,那么就是主观宕机。
·odown 是客观宕机,如果 quorum 数量的哨兵都觉得一个 master 宕机了,那么就是客观宕机。
sdown 达成的条件很简单,如果一个哨兵 ping一个master,超过了 is-master-down-after-milliseconds 指定的毫秒数之后,就主观认为 master 宕机了;如果一个哨兵在指定时间内,收到了 quorum 数量的其它哨兵也认为那个 master 是 sdown 的,那么就认为是 odown 了。
6.哨兵集群的自动发现机制
哨兵互相之间的发现,是通过Redis的 pub/sub 系统实现的,每个哨兵都会往_sentinel--:hello 这个 channel 里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在。
每隔两秒钟,每个哨兵都会往自己监控的某个 master+slaves 对应的 --sentinel--:hellochannel里发送一个消息,内容是自己的 host、ip 和 runid 还有对这个 master 的监控配置
每个哨兵也会去监听自己监控的每个master+slaves 对应的 --sentinel--:hello channel,然后去感知到同样在监听这个 master+slaves 的其他哨兵的存在。
每个哨兵还会跟其他哨兵交换对master的监控配置,互相进行监控配置的同步,
(ps:一个点赞一份爱,点个关注不迷路!)