Redis哨兵机制

1.定义

哨兵,英文名 Sentinel,是一个分布式系统,用于对主从结构中的每一台服务器进行监控,当主节点出现故障后通过投票机制来挑选新的主节点,并且将所有的从节点连接到新的主节点上。

Redis Sentinel 包含若干个 Sentinel 节点和 Redis 数据节点,每个 Sentinel 节点会对数据节点和其余 Sentinel 节点进行监控,当它发现节点不可达时,会对节点做下线标识。如果被标识的是主节点,它还会和其他 Sentinel 节点进行“协商”,当大多数 Sentinel 节点都认为主节点不可达时,它们会选举出一个 Sentinel 节点来完成自动故障转移的工作,同时会将这个变化实时通知给 Redis 应用方。整个过程完全是自动的,不需要人工来介入,所以这套方案很有效地解决了 Redis 的高可用问题

Sentinel 节点本身就是独立的 Redis 节点,只不过它们有一些特殊,它们不存储数据,只支持部分命令

Sentinel 节点集合是由若干个 Sentinel 节点组成的,这样即使个别 Sentinel 节点不可用,整个 Sentinel 节点集合依然是健壮的

对于节点的故障判断是由多个 Sentinel 节点共同完成,这样可以有效地防止误判

2.架构

典型的哨兵架构图如上图所示,它主要包括两个部分:哨兵节点和数据节点。

  • 哨兵节点:哨兵系统由若干个哨兵节点组成。其实哨兵节点就是一个特殊的 Redis 节点,只不过它是不存储数据的和仅支持部分命令

  • 数据节点:主从复制结构,由主节点和从节点组成的数据节点 本质是主从复制关系

3.哨兵的作用

  • 监控:监控主节点和从节点是否正常运行;检测主节点是否存活,主节点和从节点运行情况。

  • 通知:哨兵检测的服务器出现问题时,会向其他的哨兵发送通知,哨兵之间就相当于一个微信群,每个哨兵发现的问题都会发在这个群里。

  • 自动转移故障:当检测到主节点宕机后,断开与宕机主节点连接的所有从节点,在从节点中选取一个作为主节点,然后将其他的从节点连接到这个最新主节点的上。并且告知客户端最新的服务器地址。实现从节点晋升为主节点并维护后续正确的主从关系

  • 配置提供者:在 Redis Sentinel 结构中,客户端在初始化的时候连接的是 Sentinel 节点集合,从中获取主节点信息 即客户端通过连接哨兵来获得当前Redis服务的主节点地址

4.哨兵故障转移流程

  • 主节点出现故障,此时两个从节点与主节点失去连接,主从复制失败

  • 每个 Sentinel 节点通过定期监控发现主节点出现了故障

  • 多个 Sentinel 节点对主节点的故障达成一致会选举出其中一个节点作为领导者负责故障转移

  • Sentinel 领导者节点执行了故障转移,整个过程基本是跟我们手动调整一致的,只不过是自动化完成的

  • 故障转移后整个 Redis Sentinel 的结构,重新选举了新的主节点,并下发通知各节点,客户端

5.哨兵核心配置

配置文件名称 sentinel.conf

一般配置

bind:服务监听地址,用于客户端连接,默认本机地址
daemonize:是否以后台daemon方式运行
protected-model:安全保护模式
port:端口
logfile:日志文件路径
pidfile:pid文件路径
dir:工作目录

5.1sentinel monitor mymaster

sentinel monitor mymaster <master-name> <ip> <redis-port> <quorum>

sentinel monitor mymaster 127.0.0.1 7000 2

监控的主节点的名字、IP 和端口,最后一个2的意思是有几台 Sentinel 发现有问题,就会发生故障转移,例如 配置为2,代表至少有2个 Sentinel 节点认为主节点不可达,那么这个不可达的判定才是客观的。对于设置的越小,那么达到下线的条件越宽松,反之越严格。一般建议将其设置为 Sentinel 节点的一半加1,注意:最后的参数不得大于conut(sentinel)

quorum 确认客观下线的最少的哨兵数量

5.2 sentinel down-after-millseconds

sentinel down-after-millseconds mymaster 30000:哨兵连接主节点多长时间没有响应就代表挂了。后边 30000 是毫秒,也就是 30 秒。主观上认为主节点下线

5.3 sentinel parallel-syncs mymaster

 sentinel parallel-syncs mymaster 1:

当 Sentinel 节点集合对主节点故障判定达成一致时,Sentinel 领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,parallel-syncs 就是用来限制在一次故障转移之后,每次向新的主节点发起复制操作的从节点个数,指出 Sentinel 属于并发还是串行。1代表每次只能复制一个,可以减轻 Master 的压力

5.4 sentinel auth-pass

sentinel auth-pass <master-name> <password>:如果 Sentinel 监控的主节点配置了密码,sentinel auth-pass 配置通过添加主节点的密码,防止 Sentinel 节点对主节点无法监控

5.5 sentinel failover-timeout

sentinel failover-timeout mymaster 180000:表示故障转移的时间,在进行同步的过程中,多长时间完成算有效,系统默认值是 3 分钟 如果超过设置的毫秒,表示故障转移失败

5.6 sentinel notification-script <master-name> <script-path>

配置当某一事件发生时所需要执行的脚本

5.7 sentinel client-reconfig-script <master-name> <script-path>

客户端重新配置主节点参数脚本

6.Sentinel 实现原理

6.1 检测问题

主要讲的是三个定时任务,这三个内部的执行任务可以保证出现问题马上让 Sentinel 知道

每10秒每个 Sentinel 对 Master 和 Slave 执行一次 Info Replication: 指的是 Redis Sentinel 可以对 Redis 节点做失败判断和故障转移,在 Redis 内部有三个定时任务作为基础,来 Info Replication 发现 Slave 节点,这个命令可以确定主从关系

每2秒每个 Sentinel 通过 Master 节点的 channel 交换信息(pub/sub):类似于发布订阅,Sentinel 会对主从关系进行判定,通过 sentinel:hello 频道交互。了解主从关系可以帮助更好的自动化操作 Redis。然后 Sentinel 会告知系统消息给其它 Sentinel 节点,最终达到共识,同时 Sentinel 节点能够互相感知到对方

每1秒每个 Sentinel 对其他 Sentinel 和 Redis 执行 ping:指的是对每个节点和其它 Sentinel 进行心跳检测,它是失败判定的依据。

6.2 发现问题

主要讲的是主观下线和客观下线。当有一台 Sentinel 机器发现问题时,它就会主观对它主观下线,但是当多个 Sentinel 都发现有问题的时候,才会出现客观下线。

主观下线:对于一个哨兵认为主节点在设置的时间范围内没有回复或挂机

客观下线:半数哨兵认为主节点在设置的时间范围内没有回复或挂机

6.3 解决问题

找到解决问题的人,主要讲的是领导者选举,如何在 Sentinel 内部多台节点做领导者选举,选出一个领导者

领导者选举方式

  • 每个做主观下线的sentinel节点,会向其他的sentinel节点发送命令,要求将它设置成为领导者

  • 收到命令sentinel节点,如果没有同意通过其它节点发送的命令,那么就会同意请求,否则就会拒绝

  • 如果sentinel节点发现自己票数超过半数,同时也超过了sentinel monitor mymaster 127.0.0.1 6379 2 超过2个的时候,就会成为领导者

  • 开始进行故障转移操作

哨兵领导者,兵王如何选出来的?-> Raft算法

监视该主节点的所有哨兵都有可能被选为领导者,选举使用的算法是Raft算法;Raft算法的基本思路是先到先得:即在一轮选举中,哨兵A向B发送成为领导者的申请、如果B没有同意过其他哨兵,则会同意A成为领导者。

如何选择“合适的”Slave 节点: 依次对比

  • slave-priority/replica- priority Redis 内部其实是有一个优先级配置的,在配置文件中 slave-priority,这个参数是 Salve 节点的优先级配置,设置从机的优先级,值越小,优先级越高,用于选举主机时使用 如果存在则返回,如果不存在则继续。

  • 复制偏移量最大 当上面这个slave-priority优先级不满足的时候,Redis 还会选择复制偏移量最大的 Slave节点,如果存在则返回,如果不存在则继续。之所以选择偏移量最大,这是因为偏移量越小,和 Master 的数据越不接近,现在 Master挂掉了,说明这个偏移量小的机器数据也可能存在问题,这就是为什么要选偏移量最大的 Slave 的原因。

  • runid 最小的节点 如果发现偏移量都一样,这个时候 Redis 会默认选择 runid 最小的节点 字典顺序 ASCII码

7.生产环境中部署技巧

Sentinel 节点不应该部署在一台物理“机器”上,这里特意强调物理机是因为一台物理机做成了若干虚拟机或者现今比较流行的容器,它们虽然有不同的 IP 地址,但实际上它们都是同一台物理机,同一台物理机意味着如果这台机器有什么硬件故障,所有的虚拟机都会受到影响,为了实现 Sentinel 节点集合真正的高可用,请勿将 Sentinel 节点部署在同一台物理机器上。

部署至少三个且奇数个的 Sentinel 节点 3个以上是通过增加 Sentinel 节点的个数提高对于故障判定的准确性,因为领导者选举需要至少一半加1个节点,奇数个节点可以在满足该条件的基础上节省一个节点

8.哨兵的命令

- SENTINEL masters: 显示被监控的所有master以及它们的状态
- SENTINEL master <master name> :显示指定master的信息和状态
- SENTINEL slaves <master name>: 显示指定master的所有slave以及它们的状态;
- SENTINEL get-master-addr-by-name <master name> :返回指定master的ip和端口,如果正在进行failover或者failover已经完成,将会显示被提升为master的slave的ip和端口。
- SENTINEL failover <master name> :强制sentinel执行failover,并且不需要得到其他sentinel的同意。但是failover后会将最新的配置发送给其他sentinel。
- sentinel monitor test 127.0.0.1 6379 2 :  添加新的监听
- SENTINEL REMOVE test:   放弃对某个master监听
- SENTINEL failover-timeout mymaster 180000: 指定故障切换允许的毫秒数,超过这个时间,就认为故障切换失败,默认为3分钟
- info::sentinel的基本状态信息

9.哨兵常见问题

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

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

解决异步复制导致数据丢失:min-slaves-max-lag 10

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

解决集群脑裂导致的数据丢失:min-slaves-to-write 1

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

总之:

min-slaves-to-write 1

min-slaves-max-lag 10

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

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

10.哨兵部署实战

10.1 准备工作

角色IP端口服务运行模式
哨兵1192.168.211.12826379sentinel1
哨兵2192.168.211.12926379sentinel2
哨兵3192.168.211.13026379sentinel3
主机192.168.211.1286379Master
从机192.168.211.1296379Slave
从机192.168.211.1306379Slave

启动顺序:主机 ->从机 -> 哨兵

10.2 哨兵配置文件

vi ./etc/redis-sentinel.conf

# 设置绑定地址,使之可以被外部访问(绑定哨兵所在机器的ip地址)
bind 0.0.0.0

#默认端口
port 26379

# 是否是后台应用程序,默认是no,修改成yes后台启动
daemonize yes

# 指定别名  主节点地址  端口  哨兵个数(有几个哨兵监控到主节点宕机执行转移)
# 告诉sentinel去监听地址为ip:port的一个master
# master-name可以自定义,master-name只能包含英文字母,数字,和“.-_”这三个字符
# quorum是一个数字,指明当有多少个sentinel认为一个master失效时,master才算真正失效
# 需要注意的是 master-ip 要写真实的ip地址而不要用回环地址(127.0.0.1)。
sentinel monitor mymaster  192.168.1.75 6379 1

# 如果哨兵3s内没有收到主节点的心跳,哨兵就认为主节点宕机了,默认是30秒
# 这个配置项指定了需要多少失效时间,一个master才会被这个sentinel主观地认为是不可用的。 单位是毫秒,默认为30秒
sentinel down-after-milliseconds mymaster 30000

# 选举出新的主节点之后,可以同时连接从节点的个数
# 这个配置项指定了在发生failover主备切换时最多可以有多少个slave同时对新的master进行同步,这个数字越小,完成failover所需的时间就越长,但是如果这个数字越大,就意味着越多的slave因为replication而不可用。可以通过将这个值设为 1 来保证每次只有一个slave 处于不能处理命令请求的状态
sentinel parallel-syncs mymaster 1

# 如果10秒后,master仍没活过来,则启动failover,默认180s
sentinel failover-timeout mymaster 180000

# 配置连接redis主节点密码(如果需要的话进行配置)
# 设置连接master和slave时的密码,注意的是sentinel不能分别为master和slave设置不同的密码,因此master和slave的密码应该设置相同。
# 注意:主从auth密码需要一致,且主从复制配置模块密码都要配置并与auth相同
sentinel auth-pass mymaster ljy1286735

# 配置日志 重要 出错可查询
# 日志名称
logfile "26379.log"

# 日志路径
dir './'

10.3启动哨兵

#启动服务端
redis-server ./etc/redis-sentinel.conf --sentinel
redis-sentinel ./sentinel.conf

#启动客户端
redis-cli -p 26379

#信息查看
info sentinel

# 成功如
[root@localhost bin]# redis-cli -p 26379
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.75:6379,slaves=2,sentinels=3

Redis 中如何解决 The TCP backlog setting of 511 cannot be enforced 告警问题?

  • 方式一:设置的值128较低,需要“echo 511 > /proc/sys/net/core/somaxconn”命令,注意此命令只是暂时生效,如果重启后就会失效。

  • 方式二:永久解决Redis中The TCP backlog setting of 511 cannot be enforced告警问题,编辑/etc/sysctl.conf文件,添加net.core.somaxconn = 1024然后执行sysctl -p命令查看是否添加成功,之后重启Redis服务即可

报错信息 Creating Server TCP listening socket 127.0.0.1:6379: bind: Address already in use

  • 在linux终端命令行中运行:

    redis-cli 127.0.0.1:6379> shutdown not connected> exit

  • 再次启动Redis服务 redis-sentinel ./sentinel.conf

# 删除进程
ps -auf | grep redis
kill -9 进程号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微刻时光

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值