Redis 哨兵机制

文若2年前技术文章483


前言

Redis 主从复制模式下,一旦主节点出现了故障不可达,需要人工干预进行故障转移,无论对于 Redis 的应用方还是运维方都带来了很大的不便。对于应用方来说无法及时感知到主节点的变化,必然会造成一定的写数据丢失和读数据错误,甚至可能造成应用方服务不可用。对于 Redis 的运维方来说,整个故障转移的过程是需要人工来介入的,故障转移实时性和准确性上都无法得到保障。Redis 2.8 版本提供哨兵机制,可以解决此类问题。本篇文章介绍哨兵安装部署及原理。

1. 安装部署

1.1 环境介绍

操作系统版本:CentOS Linux release 7.8.2003 (Core)

Redis 版本:Redis server v5.0.12

角色

IP

端口

说明

Master

172.16.104.57

6379

Redis 主节点

slave-1

172.16.104.55

6379

slave-1 从节点

slave-2

172.16.104.56

6379

slave-2 从节点

sentinel-1

172.16.104.57

26379

sentinel-1 节点

sentinel-2

172.16.104.55

26379

sentinel-2 节点

sentinel-3

172.16.104.56

26379

sentinel-3 节点

Redis 单机部署参考:Redis 源码安装

1.2 建立复制关系

分别在两个从节点执行下方命令:

slaveof 172.16.104.57 6379

主节点有密码的话,记得配置 masterauth 参数。

查看复制状态 connected_slaves = 2 表示两台从库都在线。

127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:2
slave0:ip=172.16.104.55,port=6379,state=online,offset=434,lag=1
slave1:ip=172.16.104.56,port=6379,state=online,offset=434,lag=0
master_replid:9898532eb9351f1c4322e01589a344d4632a70e1
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:434
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:434

1.3 部署哨兵节点

1.3.1 编辑配置

编辑 sentinel 节点的配置文件,所有节点都相同,因为是部署在不同的物理机上面。

port 26379
daemonize yes
logfile "redis-sentinel-log.log"
dir /usr/local/redis/data
sentinel monitor mymaster 172.16.104.57 6379 2
sentinel down-after-milliseconds mymaster 10000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel auth-pass mymaster Redis123

PS:配置含义可参考 1.4 哨兵配置说明

1.3.1 启动哨兵

使用 redis-sentinel 命令启动哨兵。

redis-sentinel sentinel-26379.conf

1.3.2 验证

Sentinel 节点本质上是一个特殊的 Redis 节点,可以使用 info 命令查询相关信息。

从下面的片段来看,Sentinel 找到主节点 172.16.104.57并感知到有两个从节点及三个 Sentinel 节点。

redis-cli -h 127.0.0.1 -p 26379 info Sentinel

carbon.png

1.4 哨兵配置说明

了解 Sentinel 节点的参数的含义,可以帮助更加合理的使用哨兵模式。下面是 1.3.1 使用的配置,将以此为例进行补充说明。

# 端口
port 26379
# 后台启动
daemonize yes
# 日志文件名称
logfile "redis-sentinel-log.log"
# 工作目录
dir /usr/local/redis/data
# 后面将详细说明介绍
sentinel monitor mymaster 172.16.104.57 6379 2
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
sentinel auth-pass mymaster Redis123

1.4.1 sentinel monitor

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

其中 master-name 表示哨兵监控主节点的名称,用于区分多个主节点,用户可自行指定。<ip> 和 <port> 表示需要监控主节点的 ip 和端口 <quorum> 代表要判定主节点最终不可达的票数,一般建议设置为 sentinel 节点数的一半加 1。

从刚才使用的配置文件中发现并没有指定从节点的信息,不是因为不会监控从节点,而是 sentinel 启动后会自动从主节点获取从节点以及其它 sentinel 节点的信息。这点可以从启动后点配置文件中体现。

carbon-1.png

1.4.2 sentinel down-after-milliseconds

sentinel down-after-milliseconds <master-name> <times>

每个 sentinel 节点都会周期性发生 ping 命令来判断 Redis 节点及 sentinel 节点是否可达,如果超过 down-after-milliseconds 配置的时间且没有有效回复,则判断节点不可达,其中 <times> 单位为毫秒,代表超时时间。

1.4.3 sentinel parallel-syncs

当 Sentinel 节点集合对主节点故障判定达成一致时,Sentinel 领导者节点会做故障转移操作,选出新的主节点,原来的从节点会向新的主节点发起复制操作,parallel-syncs 就是用来限制一次故障转移后,每次向主节点发起复制操作的从节点个数。

如果该参数配置较大,那么意味着故障转移后,将有多个节点同时向主库发起复制操作,尽管不会堵塞主节点正常响应,但是必然会对主节点造成一定的网络和磁盘 IO 开销。

parallel-syncs = 3 表示同时发起复制

parallel-syncs = 1 表示从节点会轮询发起复制

1.4.4 sentinel failover-timeout

sentinel failover-timeout <master-name> <times>

failover-timeout 表示故障转移超时时间。

1.4.5 sentinel auth-pass

sentinel auth-pass <master-name> <password>

主节点如果有设置密码,则也需要写到 sentinel 的配置中。

1.4.6 sentinel notification-script

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

故障转移期间,当一些告警级别的 sentinel 事件发生时,会触发 <script-path> 路径下的脚本,并向脚本发送故障参数。

1.4.7 sentinel client-reconfig-script

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

设置通知脚本。

1.5 哨兵 API

1.5.1 调整配置

可以使用 sentinel set 命令调整哨兵的配置,仅对当前节点生效。

sentinel set mymaster quorum 2

1.5.2 展示主节点信息

sentinel masters <master-name>

1.5.3 展示从节点信息

sentinel slaves <master-name>

1.5.4 手动切换

手动对主节点进行故障切换,无需协商,在日常运维中是重要的命令。

sentinel failover <master-name>

1.5.5 检查哨兵是否有效

检测当前可达的 Sentinel 节点总数是否达到 <quorum> 的个数。例如 quorum=3,而当前可达的 Sentinel 节点个数为 2 个,那么将无法进行故障转移,Redis Sentinel 的高可用特性也将失去。

sentinel ckquorum <master-name>

carbon-2.png

2. 实现原理

2.1 三个定时任务

一套合理的监控机制是 Sentinel 判定节点不可达的重要保证,Redis Sentinel 通过三个定时监控任务完成对各节点的状态监控。

  • 每隔 10 秒,每个 Sentinel 节点会向 Redis 主库和从库发送 info 命令获取最新的拓扑结构。

    • 作用 1:通过执行 info 命令,获取最新的拓扑信息,这也是哨兵不需要主动指定从节点的原因。

    • 作用 2:当有新节点加入时,会快速感知到。

    • 作用 3:节点不可达或者故障转移后,可以通过 info 命令实时更新节点拓扑信息。

  • 每隔 2 秒,每个 Sentinel 节点会向 Redis 数据节点的 sentinel:hello 频道,发送该哨兵节点对于主节点状态的判断信息及当前 Sentinel 节点的信息,同时每个 Sentinel 节点也会通过该频道获取其他节点对主节点的判断。

    • 作用 1:主动发现新的 Sentinel 节点,并与该节点创建连接。

    • 作用 2:与其他哨兵节点交换主库状态,作为客观下线及领导者选举的依据。

  • 每隔 1 秒,每个 Sentinel 节点会向所有 主节点、从节点、Sentinel 节点发送 ping 命令做一次心跳检测,来确认对应节点是否可达,是判断节点是否下线的重要依据。

2.2 主观下线与客观下线

2.2.1 主观下线

从 2.1 可以了解到,每隔 1 秒会向所有节点发送 ping 命令,如果超过 down-after-milliseconds 配置的时间,没有有效回复,Sentinel 节点就会对该节点进行失败判断,这个行为叫做主观下线。主观下线仅表示当前 Sentinel 节点的一家之言,存在误判的可能。

2.2.2 客观下线

当  Sentinel 主观下线的节点是主节点时,该 Sentinel 节点会向其他 Sentinel 节点询问对主节点的判断,当认为主节点下线的 Sentinel 节点个数大于 <quorum> 个数,那么就确认主节点确实已下线,这时该 Sentinel 节点会做出客观下线的决定,这样客观下线的含义是比较明显了,也就是大部分 Sentinel 节点都对主节点的下线做了同意的判定,那么这个判定就是客观的。

2.3 选主机制

2.3.1 哨兵领导者选举

当 Sentinel 节点对 Redis 主节点确认客观下线,此时需要选择一个 Sentinel 节点作为领导者,完成故障转移工作。Redis Sentinel 选主使用的算法是 Raft,算法比较复杂,感兴趣可以看论文 Raft 论文

2.3.2 故障转移

选举出的领导者 Sentinel 节点将进行 Redis 数据节点故障转移,此时需要对各从节点进行筛选,具体步骤为:

  1. 过滤已经主观下线、断线、5 秒内没有回复 Sentinel 节点 ping 响应、与主节点断连时间超过 down-after-milliseconds * 10 秒。

  2. 选择 replica-priority 预设从节点优先级列表最高的实例,如果没有则进行下一步。

  3. 选择复制偏移量最大的从节点,表示复制的数据最完整,偏移量都相同则进行下一步。

  4. 选择 runid 最小的从节点。

Sentinel 节点集合会对原来的主库保持关注,当其恢复正常会命令它复制新的主节点。

后记

2020 年美国科技界纷纷响应 Black Lives Matter,BLM 维权运动,将带有种族色彩的词汇替换。

文章中关于 slave 命令或参数,如果不好使,可以尝试替换为 replica 试试。

参考:

【1】 Redis 官方文档 https://redis.io

【2】《Redis 开发与运维》

【3】《Redis 核心技术与实战》




相关文章

Hbase热点现象

热点现象:HBase热点现象是指在分布式存储系统HBase中,由于数据访问不均衡而导致部分Region Server负载过重的情况。这种不均衡通常是由于某些特定的数据行或列族频繁地被访问,从而导致某个...

Redis Sentinel与Cluster安装部署(三)

4.3redis-cluster-resharding重新分配槽1、查看当前集群节点状态信息 # redis-cli --cluster check 172.32.1.59:7000 -a dt20...

使用Sqoop将数据从Hive导入MySQL(一)

使用Sqoop将数据从Hive导入MySQL(一)

使用Sqoop将数据从Hive导入MySQL首先查看csv数据类型创建类似的hive表并导入数据CREATE TABLE data (    province STRING,    code INT,...

TDengine集群部署

TDengine集群部署

1、基础环境操作系统:centos7.9内核版本:3.10下载地址:https://docs.taosdata.com/releases/tdengine/#3110架构设置:3 dnode,3 mn...

MySQL运维实战(2)MySQL用户和权限管理

MySQL用户管理基本命令创建用户使用create user命令创建用户create user 'username'@'host' ide...

静默安装oracle11g单实例

环境: CentOS 7.8 11.2.0.4.0 orclp:172.16.104.31一、准备1、依赖包检查pdksh 在 redhat 上叫 ksh检查是否有安装root# rpm -q bin...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。