数据库
首页 > 数据库> > redis 哨兵架构

redis 哨兵架构

作者:互联网

什么是哨兵(哨兵的介绍)

哨兵的核心知识点

为什么 redis 哨兵集群只有 2 个节点无法正常工作

哨兵集群必须部署 2 个以上的节点,如果哨兵集群仅仅部署了 2 个哨兵实例,quorum = 1

+----+         +----+
| M1 |---------| R1 |
| S1 |---------| S2 |
+----+         +----+

Configuration:quorum = 1
master 宕机,s1 和 s2 中只要有 1 个哨兵认为 master 宕机就可以进行切换,同时 s1 和 s2 中会选举出一个哨兵来执行故障转移。同时这个时候,需要 majority,也就是大多数哨兵都是运行的,2个哨兵的 majority 就是2(2的majority=2,3的majority=2,4的majority=3,5的majority=3),2个哨兵都运行着,就可以允许执行故障转移;但是如果整个 M1 和 S1 运行的机器宕机了,那么哨兵只有1个了,此时就没有 majority 来允许执行故障转移,虽然另外1台机器中还有一个R1,但是故障转移不会执行

经典的 3 个节点哨兵集群


       +----+
       | M1 |
       | S1 |
       +----+
          |
+----+    |    +----+
| R2 |----+----| R3 |
| S2 |         | S3 |
+----+         +----+

Configuration: quorum = 2
如果M1所在机器宕机了,那么三个哨兵还剩下2个,S2和S3可以一致认为master宕机,然后选举出一个来执行故障转移;同时3个哨兵的majority是2,所以还剩下的2个哨兵运行着,就可以允许执行故障转移

redis 哨兵主备切换产生的两种数据丢失问题

异步复制导致的数据丢失

因为 master->slave 的复制是异步的,所以可能有部分数据还没复制到 slave,master 就宕机了,此时这些部分数据就丢失了

脑裂导致的数据丢失

脑裂,也就是说,某个 master 所在机器突然脱离了正常的网络,跟其他 slave 机器不能连接,但是实际上 master 还运行着;此时哨兵可能就会认为 master 宕机了,然后开启选举,将其他 slave 切换成了 master。这个时候,集群里就会出现有两个 master,也就是所谓的脑裂
此时虽然某个 salve 被切换成了 master,但是 client 还没来得及切换到新的 master,还继续写向旧 master 的数据可能也丢失了,因此旧 master 再次恢复 的时候,会被作为一个 slave 挂到新的 master 上去,自己的数据会清空,重新从新的 master 恢复数据

怎么解决异步复制和脑裂导致的数据丢失

# 下面2个配置可以减少异步复制和脑裂导致的数据丢失
# 要求至少有1个 slave,数据复制和同步的延迟不能超过10秒
# 如果说一旦所有的 slave,数据复制和同步的延迟都超过了10秒钟
# 那么这个时候,master 就不会再接受任何请求了
min-slaves-to-write 1
min-slaves-max-lag 10

redis 哨兵核心原理

sdown 和 odown 转换机制

sdown 和 odown 两种失败状态
sdown 是主观宕机,就一个哨兵,如果自己觉得一个 master 宕机了,那么就是主观宕机
odown 是客观宕机,如果 quorum 数量的哨兵觉得一个 master 宕机了,那么就是客观宕机
sdown 达成的条件很简单,如果一个哨兵 ping 一个 master,超过了 is-master-down-after-milliseconds 指定的毫秒数之后,就主观认为 master 宕机
sdown 到 odown 转换的条件很简单,如果一个哨兵在指定时间内,收到了 quorum 指定数量的其他哨兵也认为那个 master 是 sdown了,那么就认为是 odown了,客观认为 master 宕机

哨兵集群的自动发现机制

哨兵互相之间的发现,是通过 redis 的 pub/sub 系统实现的,每个哨兵都会往 sentinel:hello 这个channel 里发送一个消息,这时候所有其他哨兵都可以消费到这个消息,并感知到其他的哨兵的存在
每隔2秒钟,每个哨兵都会往自己监控的某个 master + slaves 对应的 sentinel:hello channel 里发送一个消息,内容是自己的 host、ip 和 runid 还有对这个 master 的监控配置
每个哨兵也会去监听自己监控的每个 master + slaves 对应的 sentinel:hello channel,然后去感知到同样在监听这个 master + slaves 的其他哨兵的存在
每个哨兵还会跟其他哨兵交换对 master 的监控配置,互相进行监控配置的同步

slave 配置的自动纠正

哨兵会负责自动纠正 slave 的一些配置,比如 slave 如果要成为潜在的 master 候选人,哨兵会确保 slave 在复制现有 master 的数据;如果 slave 连接到了一个错误的 master 上,比如故障转移之后,那么哨兵会确保它们连接到正确的 master 上

slave-master 选举算法

如果一个 master 被认为 odown 了,而且 majority 哨兵都允许了主备切换,那么某个哨兵就会执行主备切换操作,此时首先要选举一个 slave 来
会考虑 slave 的一些信息

如果一个 slave 跟 master 断开连接已经超过了 down-after-milliseconds 的 10倍,外加 master 宕机的时长,那么 slave 就被认为不适合选举为 master

(down-after-milliseconds * 10) + milliseconds_since_master_is_in_SDOWN_state

接下来会对 slave 进行排序

quorum 和 majority

每次一个哨兵要做主备切换,首先需要 quorum 数量的哨兵认为 odown,然后选举出一个哨兵来做切换,这个哨兵还得得到 majority 哨兵的授权,才能正式执行切换
如果 quorum < majority,比如5个哨兵,majority就是3,quorum设置为2,那么就3个哨兵授权就可以执行切换
但是如果 quorum >= majority,那么必须 quorum数量的哨兵都授权,比如5个哨兵,quorum是5,那么必须5个哨兵都同意授权,才能执行切换

configuration epoch

哨兵会对一套redis master+slave进行监控,有相应的监控的配置。执行切换的那个哨兵,会从要切换到的新master(slave->master)那里得到一个configuration epoch,这就是一个version号,每次切换的version号都必须是唯一的
如果第一个选举出的哨兵切换失败了,那么其他哨兵,会等待failover-timeout时间,然后接替继续执行切换,此时会重新获取一个新的configuration epoch,作为新的version号

configuraiton传播

哨兵完成切换之后,会在自己本地更新生成最新的master配置,然后同步给其他的哨兵,就是通过之前说的pub/sub消息机制.这里之前的version号就很重要了,因为各种消息都是通过一个channel去发布和监听的,所以一个哨兵完成一次新的切换之后,新的master配置是跟着新的version号的.其他的哨兵都是根据版本号的大小来更新自己的master配置的

哨兵配置

主要配置

三台机器配置哨兵,配置文件sentinal.conf

# 主要配置 sentinal.conf
# 端口配置无所谓,这里以 5000 为端口号
# 哨兵默认端口  26379
port 5000
# bind 自己的 ip
bind 192.168.1.132
# 配置监听的主服务器
sentinel monitor mymaster 192.168.1.132 6379 2
# 设置主节点多长时间没有响应就代表挂了,
# 后边 30000 是毫秒,也就是 30 秒。
sentinel down-after-milliseconds mymaster 30000
# 同步的过程中,多长时间完成算有效
sentinel failover-timeout mymaster 60000
# 故障转移时,最多有多少个从节点对新的主节点进行同步
sentinel parallel-syncs mymaster 1
# 主要配置 sentinal.conf
# 端口配置无所谓,这里以 5000 为端口号
port 5000
# bind 自己的 ip
bind 192.168.1.133
# 配置监听的主服务器
sentinel monitor mymaster 192.168.1.132 6379 2
# 设置主节点多长时间没有响应就代表挂了,
# 后边 30000 是毫秒,也就是 30 秒。
sentinel down-after-milliseconds mymaster 30000
# 同步的过程中,多长时间完成算有效
sentinel failover-timeout mymaster 60000
# 故障转移时,最多有多少个从节点对新的主节点进行同步
sentinel parallel-syncs mymaster 1
# 主要配置 sentinal.conf
# 端口配置无所谓,这里以 5000 为端口号
port 5000
# bind 自己的 ip
bind 192.168.1.134
# 配置监听的主服务器
sentinel monitor mymaster 192.168.1.132 6379 2
# 设置主节点多长时间没有响应就代表挂了,
# 后边 30000 是毫秒,也就是 30 秒。
sentinel down-after-milliseconds mymaster 30000
# 同步的过程中,多长时间完成算有效
sentinel failover-timeout mymaster 60000
# 故障转移时,最多有多少个从节点对新的主节点进行同步
sentinel parallel-syncs mymaster 1

启动

# redis-sentinel sentinel.conf 文件地址
# 在 三台机器分别执行下面语句启动
# redis-sentinel 可能需要配置,默认情况下在 /etc/init.d 目录下运行
redis-sentinel /etc/redis/sentinel.conf

连接客户端 & 检查哨兵状态

redis-cli -h 192.168.1.133 -p 5000

sentinel master mymaster
SENTINEL slaves mymaster
SENTINEL sentinels mymaster

标签:架构,宕机,redis,哨兵,master,sentinel,slave
来源: https://www.cnblogs.com/xiaoyangabc/p/16332950.html