Redis哨兵模式
  DcpJeOZ6VzTX 2023年11月02日 24 0

Sentinel介绍

什么是sentinel

Redis-Sentinel是Redis官方推荐的高可用性(HA)解决方案,当用Redis做Master-slave的高可用方案时, 假如master宕机了,Redis本身(包括它的很多客户端)都没有实现自动进行主备切换,而Redis-sentinel 本身也是一个独立运行的进程,它能监控多个master-slave集群,发现master宕机后能进行自动切换。

sentinel架构

Sentinel 是一个监视器,它可以根据被监视实例的身份和状态来判断应该执行何种动作。

Redis哨兵模式_Sentinel持久化

sentinel功能

1)监控(Monitoring): Sentinel会不断地检查你的主服务器和从服务器是否运作正常。 2)提醒(Notification): 当被监控的某个Redis服务器出现问题时,Sentinel可以通过API向管理员或者其他应用程序发送通知。 3)自动故障迁移(Automatic failover): 当一个主服务器不能正常工作时,Sentinel会开始一次自动故障迁移操作,它会将失效主服务器的其中 一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器;当客 户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址,使得集群可以使用新主 服务器代替失效服务器。

sentinel如何发现主库从库

Sentinel通过用户给定的配置文件来发现主服务器。

Redis哨兵模式_Sentinel持久化_02

创建两个链接:

  • 订阅连接 一个哨兵,可以通过订阅连接,发现其他哨兵
  • 命令连接 1)通过主库执行info replication发现其他从库 2)切换时,取消从库身份,其他从库指向新主库
redis-sentinel sentinel.conf

############ master1 configure ##############
sentinel monitor master1 127.0.0.1 6379 2
sentinel down-after-milliseconds master1 30000
sentinel parallel-syncs master1 1
sentinel failover-timeout master1 900000

############ master2 configure ##############
sentinel monitor master2 127.0.0.1 12345 5
sentinel down-after-milliseconds master2 50000
sentinel parallel-syncs master2 5
sentinel failover-timeout master2 450000

如何发现从库

Sentinel通过向主服务器发送INFO命令来自动获得所有从服务器的地址。

Redis哨兵模式_Sentinel_03

跟主服务器一样,Sentinel 会与每个被发现的从服务器创建命令连接和订阅连接。

如何发现其他哨兵

Sentinel 会通过命令连接向被监视的主从服务器发送 “HELLO” 信息,该消息包含 Sentinel 的 IP、端口 号、ID 等内容,以此来向其他 Sentinel 宣告自己的存在。与此同时Sentinel 会通过订阅连接接收其他 Sentinel 的“HELLO” 信息,以此来发现监视同一个主服务器的其他 Sentinel 。

Redis哨兵模式_Redis哨兵_04

1)一个Sentinel可以与其他多个Sentinel进行连接,各个Sentinel之间可以互相检查对方的可用性,并 进行信息交换。你无须为运行的每个 Sentinel 分别设置其他 Sentinel 的地址,因为Sentinel可以通过发 布与订阅功能来自动发现正在监视相同主服务器的其他 Sentinel ,这一功能是通过向频道 sentinel:hello发送信息来实现的。

2)与此类似,你也不必手动列出主服务器属下的所有从服务器,因为 Sentinel 可以通过询问主服务器 来获得所有从服务器的信息。每个Sentinel会以每两秒一次的频率,通过发布与订阅功能,向被它监视 的所有主服务器和从服务器的__sentinel__:hello频道发送一条信息,信息中包含了Sentinel的IP地址、 端口号和运行ID(runid)。

3)每个Sentinel都订阅了被它监视的所有主服务器和从服务器的__sentinel__:hello 频道,查找之前未出 现过的sentinel(looking for unknown sentinels)。当一个Sentinel发现一个新的Sentinel时,它会将新 的Sentinel添加到一个列表中,这个列表保存了Sentinel已知的,监视同一个主服务器的所有其他 Sentinel 。Sentinel发送的信息中还包括完整的主服务器当前配置(configuration)。如果一个 Sentinel 包含的主服务器配置比另一个Sentinel发送的配置要旧,那么这个 Sentinel 会立即升级到新配 置上。

4)在将一个新 Sentinel 添加到监视主服务器的列表上面之前,Sentinel 会先检查列表中是否已经包含 了和要添加的 Sentinel 拥有相同运行 ID 或者相同地址(包括 IP 地址和端口号)的 Sentinel ,如果是 的话,Sentinel 会先移除列表中已有的那些拥有相同运行 ID或者相同地址的 Sentinel ,然后再添加新Sentinel 。

多个哨兵之间连接

Sentinel之间只会互相创建命令连接,用于进行通信。因为已经有主从服务器作为发送和接收HELLO信息的中介,所以Sentinel之间不会创建订阅连接。

Redis哨兵模式_Sentinel持久化_05

哨兵如何做切换

Sentinel使用PING命令来检测实例的状态:如果实例在指定的时间内没有返回回复,或者返回错误的回 复,那么该实例会被 Sentinel 判断为下线。 Redis的Sentinel中关于下线(down)有两个不同的概念:

1)主观下线(Subjectively Down, 简称 SDOWN)指的是单个 Sentinel 实例对服务器做出的下线判 断。

2)客观下线(Objectively Down,简称 ODOWN)指的是多个Sentinel实例在对同一个服务器做出 SDOWN判断,并且通过SENTINEL is-master-down-by-addr命令互相交流之后,得出的服务器下线判 断。(一个 Sentinel可以通过向另一个Sentinel发送SENTINEL is-master-down-by-addr命令来询问对方 是否认为给定的服务器已下线。)

Redis哨兵模式_Sentinel_06

如果一个服务器没有在 master-down-after-milliseconds 选项所指定的时间内,对向它送PING命令的 Sentinel返回一个有效回复(valid reply),那么Sentinel就会将这个服务器标记为主观下线。 服务器对PING命令的有效回复可以是以下三种回复的其中一种:

1)返回 +PONG 。

2)返回 -LOADING 错误。

3)返回 -MASTERDOWN 错误。 如果服务器返回除以上三种回复之外的其他回复,又或者在指定时间内没有回复Ping命令,那么 Sentinel认为服务器返回的回复无效(non-valid)。 注意:一个服务器必须在master-down-after-milliseconds毫秒内,一直返回无效回复才会被Sentinel标 记为主观下线。 举个例子,如果master-down-after-milliseconds选项的值为30000毫秒(30秒),那么只要服务器能 在每29秒之内返回至少一次有效回复,这个服务器就仍然会被认为是处于正常状态的。 从主观下线状态切换到客观下线状态并没有使用严格的法定人数算法(strong quorum algorithm), 而是使用了流言协议:如果 Sentinel 在给定的时间范围内,从其他Sentinel那里接收到了足够数量的主 服务器下线报告,那么Sentinel就会将主服务器的状态从主观下线改变为客观下线。如果之后其他 Sentinel不再报告主服务器已下线,那么客观下线状态就会被移除。 客观下线条件只适用于主服务器:对于任何其他类型的Redis实例,Sentinel在将它们判断为下线前不 需要进行协商,所以从服务器或者其他 Sentinel 永远不会达到客观下线条件。 只要一个Sentinel发现某个主服务器进入了客观下线状态,这个Sentinel就可能会被其他Sentinel推选 出,并对失效的主服务器执行自动故障迁移操作。

故障转移步骤

一次故障转移操作由以下步骤组成: 1)发现主服务器已经进入客观下线状态。 2)基于Raft leader election协议 ,进行投票选举 3)如果当选失败,那么在设定的故障迁移超时时间的两倍之后,重新尝试当选。如果当选成功,那么 执行以下步骤。 4)选出一个从服务器,并将它升级为主服务器。 5)向被选中的从服务器发送 SLAVEOF NO ONE 命令,让它转变为主服务器。 6)通过发布与订阅功能,将更新后的配置传播给所有其他Sentinel,其他Sentinel对它们自己的配置进 行更新。 7)向已下线主服务器的从服务器发送SLAVEOF命令,让它们去复制新的主服务器。 8)当所有从服务器都已经开始复制新的主服务器时, leader Sentinel 终止这次故障迁移操作。

Redis哨兵模式_Sentine故障切换_07

选举规则

Sentinel使用以下规则来选择新的主服务器: 1)在失效主服务器属下的从服务器当中,那些被标记为主观下线、已断线、或者最后一次回复PING命 令的时间大于五秒钟的从服务器都会被淘汰。 2)在失效主服务器属下的从服务器当中,那些与失效主服务器连接断开的时长超过down-after选项指 定的时长十倍的从服务器都会被淘汰。 3)在经历了以上两轮淘汰之后剩下来的从服务器中,我们选出复制偏移量(replication offset)最大 的那个从服务器作为新的主服务器; 4)如果复制偏移量不可用,或者从服务器的复制偏移量相同,那么带有最小运行ID的那个从服务器成 为新的主服务器。

sentinel故障切换后如何保持数据一致的

Sentinel自动故障迁移的一致性特质: 1)Sentinel自动故障迁移使用Raft算法来选举领头(leader)Sentinel ,从而确保在一个给定的周期 (epoch)里,只有一个领头产生。 2)这表示在同一个周期中, 不会有两个 Sentinel 同时被选中为领头,并且各个 Sentinel 在同一个节 点中只会对一个领头进行投票。 3)更高的配置节点总是优于较低的节点,因此每个 Sentinel 都会主动使用更新的节点来代替自己的配 置。 简单来说,我们可以将Sentinel配置看作是一个带有版本号的状态。一个状态会以最后写入者胜出 (last-write-wins)的方式(也即是,最新的配置总是胜出)传播至所有其他Sentinel。

sentinel持久化配置

Sentinel状态的持久化: 1)Sentinel 的状态会被持久化在 Sentinel 配置文件里面。 2)每当Sentinel接收到一个新的配置,或者当领头Sentinel为主服务器创建一个新的配置时,这个配置 会与配置节点一起被保存到磁盘里面。 3)这意味着停止和重启Sentinel进程都是安全的。

Sentinel实战

环境准备

主机

IP

角色

应用

db01

172.16.1.51

主库

redis-server、redis-client、redis-sentinel

db02

172.16.1.52

从库

redis-server、redis-client

db03

172.16.1.53

从库

redis-server、redis-client

主从复制
## 主库
[root@db01 ~]# redis-cli -a 123
127.0.0.1:6379> slaveof no one
OK
## 从库
[root@db02 redis]# redis-cli -a 123
127.0.0.1:6379> slaveof 172.16.1.51 6379
OK
## 从库
[root@db03 redis]# redis-cli -a 123
127.0.0.1:6379> slaveof 172.16.1.51 6379
OK
## 查看主从复制信息
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
min_slaves_good_slaves:2
slave0:ip=172.16.1.52,port=6379,state=online,offset=7546,lag=0
slave1:ip=172.16.1.53,port=6379,state=online,offset=7546,lag=0
master_failover_state:no-failover
master_replid:9ab26d20c2995785b39ed8a1f87cab1509a65931
master_replid2:b452962e762b8c18ec4b893feee86434eba2b12a
master_repl_offset:7546
second_repl_offset:7463
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:7463
repl_backlog_histlen:84
127.0.0.1:6379>

sentinel monitor mymaster 127.0.0.1 6379 2 Sentinel 去监视一个名为mymaster的主服务器,这个主服务器的IP地址为127.0.0.1,端口号为6379, 而将这个主服务器判断为失效至少需要2个Sentinel同意(只要同意Sentinel的数量不达标,自动故障迁 移就不会执行,不过要注意,无论你设置要多少个Sentinel同意才能判断一个服务器失效,一个 Sentinel 都需要获得系统中多数(majority) Sentinel 的支持,才能发起一次自动故障迁移,并预留一 个给定的配置节点(configuration Epoch,一个配置节点就是一个新主服务器配置的版本号)。换句 话说,在只有少数(minority)Sentinel进程正常运作的情况下,Sentinel 是不能执行自动故障迁移 的。 sentinel down-after-milliseconds mymaster 5000 指定了Sentinel认为服务器已经断线所需的毫秒数。如果服务器在给定的毫秒数之内,没有返回 Sentinel发送的Ping命令的回复,或者返回一个错误,那么Sentinel将这个服务器标记为主观下线 (subjectively down,简称SDOWN)。不过只有一个Sentinel将服务器标记为主观下线并不一定会引

起服务器的自动故障迁移:只有在足够数量的Sentinel都将一个服务器标记为主观下线之后,服务器才 会被标记为客观下线(objectively down, 简称 ODOWN ),这时自动故障迁移才会执行。 sentinel failover-timeout mymaster 180000 自动故障切换的超时时间 sentinel parallel-syncs mymaster 1 在执行故障转移时,最多可以有多少个从服务器同时对新的主服务器进行同步,这个数字越小,完成 故障转移所需的时间就越长。如果从服务器被设置为允许使用过期数据集(参见对 redis.conf 文件中 对 slave-serve-stale-data 选项的说明),那么你可能不希望所有从服务器都在同一时间向新的主服务 器发送同步请求,因为尽管复制过程的绝大部分步骤都不会阻塞从服务器,但从服务器在载入主服务 器发来的 RDB 文件时,仍然会造成从服务器在一段时间内不能处理命令请求:如果全部从服务器一起 对新的主服务器进行同步,那么就可能会造成所有从服务器在短时间内全部不可用的情况出现。可以 通过将这个值设为1来保证每次只有一个从服务器处于不能处理命令请求的状态。

部署sentinel
## 编辑sentinel配置文件
port 26379
daemonize yes
dir "/app/redis/data"
sentinel monitor lol 127.0.0.1 6379 1
sentinel down-after-milliseconds lol 5000
sentinel auth-pass lol 123
## 启动sentinel
[root@db01 ~]# redis-sentinel /app/redis/sentinel.conf

演示-停掉主库

# 停掉主库
[root@db01 ~]# systemctl stop redis

# 查看从库(6380)
[root@db01 ~]# redis-cli -a 123 -p 6380
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6380> INFO replication
# Replication
role:slave
master_host:172.16.1.51
master_port:6381            #指向主库为6381
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
slave_read_repl_offset:19137
slave_repl_offset:19137
slave_priority:100
slave_read_only:1
replica_announced:1
connected_slaves:0
master_failover_state:no-failover
master_replid:be27bdc40257a0136794135314cef42da6d116b3
master_replid2:a1c8467d4d08d713bc5387078dc324de6ebf320c
master_repl_offset:19137
second_repl_offset:17580
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:9815
repl_backlog_histlen:9323
127.0.0.1:6380> quit

# 查看6381,确实为主库
[root@db01 ~]# redis-cli -a 123 -p 6381
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6381> INFO replication
# Replication
role:master
connected_slaves:1
slave0:ip=172.16.1.51,port=6380,state=online,offset=20809,lag=1
master_failover_state:no-failover
master_replid:be27bdc40257a0136794135314cef42da6d116b3
master_replid2:a1c8467d4d08d713bc5387078dc324de6ebf320c
master_repl_offset:20809
second_repl_offset:17580
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:9759
repl_backlog_histlen:11051
127.0.0.1:6381>
【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

上一篇: Redis主从复制 下一篇: Redis消息队列
  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论