redis哨兵故障转移及实现

如题所述

第1个回答  2022-07-05

sentinel 是一个特殊的 redis 节点,它有自己专属的 api

sentinel masters

展示所有被监控的主节点状态及相关信息:

sentinel master <master name>

展示指定 <master name> 状态以及相关的信息:

sentinel slaves <master name>

展示指定 <master name> 的从节点状态以及相关的统计信息:

sentinel sentinels <master name>

展示指定 <master name> sentinel 节点集合(不包含当前 sentinel 节点):

sentinel get-master-addr-by-name <master name>

获取主节点信息:

sentinel failover <master name>

<master name> 进行强制故障转移:

修改配置:

Master 可能会因为某些情况宕机了,如果客户端是固定一个地址去访问,肯定是不合理的,所以客户端请求是请求哨兵,从哨兵获取主机地址的信息,或者是从机的信息。可以实现一个例子:

执行 docker-composer up 之后 sentinel.conf 发生了变化,每个配置文件变化如下:

sentinel\conf\sentinel.conf

sentine2\conf\sentinel.conf

sentine3\conf\sentinel.conf

从变化中可以看出每台 Sentinel 分别记录了 slave 的节点信息和其它 Sentinel 节点信息。

在宿主机中随便进入一台 Sentinel

可以观察到监听的所有 master ,将 192.168.3.2 这台 master 进行宕机

docker stop redis-master

宕机完之后等待 Sentinel 检测周期过了之后再对 sentinel.conf 和 redis.conf 进行观察。

3台 Sentinel 的 sentinel monitor mymaster 192.168.3.2 6379 2 变成了 sentinel monitor mymaster 192.168.3.4 6379 2

其次master对应的slave节点信息也进行更改。

192.168.3.3 的 redis.conf 中 replicaof 192.168.3.2 6379 也变成了 replicaof 192.168.3.4 6379 。

192.168.3.2 的 redis.conf 中 replicaof 192.168.3.2 6379 这行配置被删除掉了。

再次启动 192.168.3.2 redis 节点,而这台节点的 redis.conf 中增加了一行 replicaof 192.168.3.4 6379 。

其实就是将我们的操作自动化了。

Sentinel 的实现原理,主要分为三个步骤:

回顾上一篇文章中 Sentinel 的配置。

主观下线:每个 Sentinel 节点对 Redis 失败的“偏见”。之所以是偏见,只是因为某一台机器30s内没有得到回复。

客观下线:这个时候需要所以 Sentinel 节点都发现它30s内无回复,才会达到共识。

Redis 内部其实是有一个优先级配置的,在配置文件中 replica-priority ,这个参数是 slave 节点的优先级配置,如果存在则返回,如果不存在则继续。当上面这个优先级不满足的时候, Redis 还会选择复制偏移量最大的 Slave 节点,如果存在则返回,如果不存在则继续。之所以选择偏移量最大,这是因为偏移量越小,和 Master 的数据越不接近,现在 Master 挂掉了,说明这个偏移量小的机器数据可能存在问题,这就是为什么选择偏移量最大的 Slave 的原因。如果发现偏移量都一样,这个时候 Redis 会默认选择 runid 最小的节点。

生产环境部署技巧:

哨兵集群在发现 master node 挂掉后会进行故障转移,也就是启动其中一个 slave node master node 。在这过程中,可能会导致数据丢失的情况。

造成的问题:

​ 此时哨兵可能就会认为 master 宕机了,然后开始选举,将其它 slave 切换成 master 。这时候集群里就会有2个 master ,也就是所谓的脑裂。此时虽然某个 slave 被切换成 master ,但是可能 client 还没来得及切换成新的 master ,还继续写向旧的 master 的数据可能就丢失了。因此旧 master 再次被恢复的时候,会被作为一个 slave 挂到新的 master 上去,自己的数据会被清空,重新从新的 master 复制数据。

怎么解决:

要求至少有一个 slave ,数据复制和同步的延迟不能超过10s。

如果说一旦所有的 slave ,数据复制和同步的延迟都超过了10s,这个时候, master 就不会再接收任何请求了。

上面两个配置可以减少异步复制和脑裂导致的数据丢失。

异步复制导致的数据丢失:

​ 在异步复制的过程当中,通过 min-slaves-max-lag 这个配置,就可以确保的说,一旦 slave 复制数据和 ack 延迟时间太长,就认为可能 master 宕机后损失的数据太多了,那么就拒绝写请求,这样就可以把 master 宕机时由于部分数据未同步到 slave 导致的数据丢失降低到可控范围内。

集群脑裂导致的数据丢失:

​ 集群脑裂因为 client 还没来得及切换成新的 master ,还继续写向旧的master的数据可能就丢失了通过 min-slaves-to-write 确保必须是有多少个从节点连接,并且延迟时间小于 min-slaves-max-lag 多少秒。

客户端需要怎么做:

​ 对于 client 来讲,就需要做些处理,比如先将数据缓存到内存当中,然后过一段时间处理,或者连接失败,接收到错误切换新的 master 处理。

相似回答