Redis
Redis,Key-Value 数据库,用来保存一些不需要持久化的数据,或者是经常需要进行读取的数据(多读少写),并支持对数据设置有效期等。例如我们主备方案中的用户token信息、OLT设备信息等均使用到了Redis。
Sentinel是Redis高可用的解决方案之一,本身也是分布式的架构,包含了**「多个」Sentinel节点和「多个」**Redis节点。而每个Sentinel节点会对Redis节点和其余的Sentinel节点进行监控。主要功能是基于redis的主从复制基础上,提供节点故障检测,主节点选举,故障切换等等功能。保证服务不会因为单个redis节点宕机而出现故障。当其发现某个节点不可达时,如果是master节点就会与其余的Sentinel节点协商。当大多数的Sentinel节点都认为master不可达时,就会选出一个Sentinel节点对master执行故障转移,并通知Redis的调用方相关的变更。
Redis的主从复制:
1、同一个Master可以同步多个Slaves。
2、Slave同样可以接受其它Slaves的连接和同步请求,这样可以有效的分载Master的同步压力。
3、Master Server是以非阻塞的方式为Slaves提供服务。所以在Master-Slave同步期间,客户端仍然可以提交查询或修改请求。
4、Slave Server同样是以非阻塞的方式完成数据同步。在同步期间,如果有客户端提交查询请求,Redis则返回同步之前的数据。
5、在Slave启动并连接到Master之后,它将主动发送一个SYNC命令。此后Master将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次完全同步。而Slave服务器在接收到数据库文件数据之后将其存盘并加载到内存中。即连上之后,先进行一次全量同步。
6、此后,Master继续将所有已经收集到的修改命令,和新的修改命令依次传送给Slaves,Slave将在本次执行这些数据修改命令,从而达到最终的数据同步。后面进行增量同步。
7、 如果Master和Slave之间的链接出现断连现象,Slave可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。
Redis-Sentinel主要功能
- 监控(Monitoring):Sentinel会不断的检查你的主节点和从节点是否正常工作。
- 通知(Notification):被监控的Redis实例如果出现问题,Sentinel可以通过API(pub)通知系统管理员或者其他程序。
- 自动故障转移(Automatic failover):如果一个 master 离线,Sentinel 会开始进行故障转移,master 下的一个slave 会被选为新的 master,其他的 slave 会开始复制新的 master。应用可以通过 Redis 服务的通知机制更新新的master 地址。
- 配置提供(Configuration provider):客户端可以把 Sentinel 作为权威的配置发布者来获得最新的 master 地址。如果发生了故障转移,Sentinel 集群会通知客户端新的 master 地址,并刷新 Redis 的配置。
Sentinel 之间:自动发现机制
- Sentinel 利用 pub/sub(发布/订阅)机制,订阅了每个 master 和 slave 数据节点的
__sentinel__:hello
频道,去自动发现其它也监控了统一 master 的 sentinel 节点 - Sentinel 向每 1s 向
__sentinel__:hello
中发送一条消息,包含了其当前维护的最新的 master 配置。如果某个sentinel发现自己的配置版本低于接收到的配置版本,则会用新的配置更新自己的 master 配置 - 与发现的 Sentinel 之间相互建立命令连接,之后会通过这个命令连接来交换对于 master 数据节点的看法
监控机制:
- 定时监控 Redis 数据节点
-
- 每 10 秒每个 sentinel 向 master、slaves 节点发送
INFO
命令 - 每 2 秒每个 sentinel 通过 master 节点的 channel(名称为
__sentinel__:hello
) 交换信息(pub/sub) - 每 1 秒每个 sentinel 对其他 sentinel 和 redis master, slave 发送
PING
命令,用于心跳检测,作为节点存活的判断依据
- 每 10 秒每个 sentinel 向 master、slaves 节点发送
- 主观下线和客观下线(发现故障)
-
- 主观下线(subjectively down,SDOWN):当前 Sentinel 实例认为某个 redis 服务为”不可用”状态。Sentinel 向 redis master 数据节点发送消息后 30s(down-after-milliseconds) 内没有收到有效回复(+PONG、-LOADING 或者 -MASTERDOWN),Sentinel 会将 master 标记为下线
- **客观下线(objectively down,ODOWN):**多个 Sentinel 实例都认为 master 处于 SDOWN 状态,那么此时 master 将处于 ODOWN, ODOWN可以简单理解为master已经被集群确定为”不可用”,将会开启故障转移机制。向其他 sentinel 节点发送 sentinel
is-master-down-by-addr
消息询问数据节点情况,得知达到 quorum 数量的 sentinel 节点认为数据节点已经下线
故障处理-选举
就是选举出新的Leader-Sentinel,选举过程如下:
1、发现主库客观下线的哨兵节点(这里称为A)向每个哨兵节点发送命令要求对方选举自己为领头哨兵(leader);
2、如果目标哨兵没有选举过其他人,则同意将A选举为领头哨兵;
3、如果A发现有超过半数且超过quorum参数值的哨兵节点同意选自己成为领头哨兵,则A哨兵成功选举为领头哨兵。
4、当有多个哨兵节点同时参与领头哨兵选举时,出现没有任何节点当选可能,此时每个参选节点等待一个随机时间进行下一轮选举,直到选出领头哨兵。
故障转移(切换 Redis master 数据节点)
-
- sentinel master 选择合适的 redis slave 成为 master
slave 选择标准: -
- 健康的节点:在线的、最近成功通信过的(5s 内回复过
PING
命令)、数据比较新的(与 master 失联时间不超过 10*down-after-milliseconds) - slave-priority(slave节点优先级)最高的slave节点
- 复制偏移量最大的 slave 节点(复制的最完整)
- 选择 runId 最小的 slave 节点(启动最早的节点)
- 健康的节点:在线的、最近成功通信过的(5s 内回复过
- 执行
SLAVEOF no one
(不会删除已有数据,只是不再接受主节点新的数据变化) 命令让其成为新的 master 节点。每秒 Sentinel 向其发送一次INFO
命令,直到成功变为 master - 向剩余的 slave 节点发送
SLAVEOF 新master
命令,让他们成为新 master 节点的 slave 节点 - 让剩余的 slave 复制新 master 的数据,通过配置
sentinel parallel-syncs
(sentinel.conf) 规定了每次向新的主节点发起复制操作的从节点个数,parallel-syncs 取值越大,slave 完成复制的时间越快,但是对主节点的网络负载、硬盘负载造成的压力也越大 - 更新原来master 节点配置为 slave 节点,并保持对其进行关注,一旦这个节点重新恢复正常后,会命令它去复制新的master节点信息
- 全部故障转移工作完成后,Leader Sentinel 就会推送 +switch-master 消息,同时重置 master,重置操作会释放掉原来 master 全部的 slave 对象和监听该 master 的其他 Sentinel 对象,然后创建出新的 slave 对象。故障迁移过程中 slave 能否返回数据给客户端取决于
slave-serve-stale-data
(redis.conf) - 持续关注旧的 master,并在他重新上线后将它设置为新 master 的 slave
- sentinel master 选择合适的 redis slave 成为 master
在 sentinel 中执行 sentinel failover master
可以强制该 sentinel 节点执行故障转移,不与其他节点进行选举
我们主备方案下的Redis配置文件如下(仅列出有配置的项目):
# 开启后台启动,默认为no
daemonize yes
# 新增密码,此处设置zhkjredis@002396
requirepass "password"
# 允许从节点进行写功能
slave-read-only no
# 设置了密码,主节点需要进行密码认证
masterauth "password6"
# 如果是Slave则需要配置Master的地址
slaveof 10.10.10.238 6379
Sentinel配置文件如下(仅列出有配置的项目):
# 检查主redis节点的地址和端口信息,1代表至少1个sentinel节点认为主节点宕机才算宕机,根据实际情况进行配置
sentinel monitor mymaster 10.10.10.44 6379 1
# 主节点失联X秒后,认为主节点不可达,默认30s
sentinel down-after-milliseconds mymaster 5000
# 主节点的密码,如有的话
sentinel auth-pass mymaster password
# sentinel后台运行
daemonize yes
# 解决哨兵之间不能通信,不能进行主结节客观下线的判断,以及failover
protected-mode no