【Redis分析】(二) Sentinel

哨兵 - 高可用

哨兵(Sentinel) 是 Redis 的高可用性解决方案:由一个或多个 Sentinel 实例组成的 Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所有从服务器。

Sentinel 可以在被监视的主服务器进入下线状态时,自动将下线主服务器的某个从服务器升级为新的主服务器,然后由新的主服务器代替已下线的主服务器继续处理命令请求。

Sentinel 的作用总结:

  1. 监控
  2. 故障转移: Redis Master 下线时, 自动选举新的 Master
  3. 通知: 使用 Sentinel 时, 客户端通过 Sentinel 获得 Redis 服务器地址, Sentinel 会自动通知最新的 Master 连接信息给客户端;

检查主观下线状态

默认情况下,Sentinel 会以每秒一次的频率向所有与它创建了连接的实例(包括主服务器、从服务器、其他 Sentinel 在内的所有机器)发送 PING 命令来判断实例是否在线。

如果一个实例在 down-after-miliseconds 毫秒内,连续向 Sentinel 返回无效回复,那么 Sentinel 会标记这个实例已经进入主观下线状态。

检查客观下线状态

当 Sentinel 将一个主服务器判断为主观下线之后,为了确定这个主服务器是否真的下线了,它会向同样监视这一服务器的其他 Sentinel 进行询问,看它们是否也认为主服务器已经进入了下线状态(可以是主观下线或者客观下线)。

当 Sentinel 从其他 Sentinel 那里接收到 quorum 个已下线判断之后,Sentinel 就会将服务器置为客观下线,在 flags 上打上 SRI_O_DOWN 标识,并对主服务器执行故障转移操作。

对于每个 Redis 结点, quorum 是独立配置的; 不同的结点 quorum 可以不同;

故障转移

当哨兵监测到某个主节点客观下线之后 (从节点下线不会干啥) ,就会开始故障转移流程。核心流程如下:

  1. 发起一次选举,选举出领头 Sentinel, 由领头哨兵去触发故障转移;

  2. 需要超过半数个的哨兵授权, 才能真正进行故障转移; 并且, Sentinel 结点的数量是固定的, 假设本来有 5 个 Sentinel结点, 现在有三个掉线了, 那么永远都无法获得超过半数的授权, 永远都无法故障转移;

  3. 根据 Redis 官方文档, quorum 仅用来判断客观下线状态, 如果要执行故障转移, 需要超过半数的 Sentinel 结点投票同意; 这也是为什么建议 Sentinel 结点数量 >= 3; 后面会再详细介绍这个问题;

    High availability with Redis Sentinel | Docs

  4. 领头 Sentinel 在已下线主服务器的所有从服务器里面,选举一个从服务器,并将其升级为新的主服务器, 会将新的配置写到配置文件里。

    1. slave 结点会有优先级配置, 越小优先级越高, 0 代表没有被选举权
    2. 优先级相同, 选主从同步的 offset 最大的(说明和上一任主机最接近)
    3. 还相同, 选 id 小的;
  5. 领头 Sentinel 将剩余的所有从服务器改为复制新的主服务器, 会将这个配置写到配置文件里。

  6. 领头 Sentinel 更新相关配置信息,当这个旧的主服务器重新上线时,将其设置为新的主服务器的从服务器。

选举新主节点的方法和选举领头 Sentinel 的方法非常相似,两者都是基于 Raft 算法的领头选举(leader election)方法来实现的。

Raft, 总结一句话 : 少数服从多数, 先到先得;

至少3个哨兵

图中, M是主节点, R是从节点, S是哨兵, C是客户端; quorum 配置为 1;

如果M1和S1下线, 那么剩下的一个哨兵有权判断客观下线, 但无权执行故障转移(因为要超过半数同意);

并且, 如果只是两台机器之间的通信断开, 并未真正下线, 那么两边都可以认为自己是主机, 所以不要这样做;

脑裂问题

脑裂是指哨兵系统中的一个主节点没有下线, 只是和从节点之间的网络断开了, 从节点被选举为新的主节点, 从而出现了多个主节点;

M1和从节点的连接断开后(没有下线), S2 和 S3 有权做故障转移, 假设M2被选举为主节点; 同时C1在往M1写入新的数据;

M1和其余两个结点的连接重新建立后, M1被设置为M2的从节点, 进行主从复制(会先清空M1原本的数据), 造成M1的数据丢失

预防数据丢失:

min-replicas-to-write 1
min-replicas-max-lag 10

当一个主节点(例如上例中的M1) 超过 max-lag 秒无法写入至少 1 个从节点时, 他将拒绝接收客户端新的写入请求;

但是, 这样又有新的问题, 如果是所有从节点下线了, 主节点就会停止工作, 即使主节点可以单机正常工作;

所以, Sentinel 并没有完全解决脑裂问题; 是一种权衡, 在可用性, 数据一致性上的权衡;

相关推荐
ketil2715 分钟前
Ubuntu 安装 redis
redis
王佑辉1 小时前
【redis】redis缓存和数据库保证一致性的方案
redis·面试
Karoku0662 小时前
【企业级分布式系统】Zabbix监控系统与部署安装
运维·服务器·数据库·redis·mysql·zabbix
gorgor在码农2 小时前
Redis 热key总结
java·redis·热key
想进大厂的小王2 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构
Java 第一深情2 小时前
高性能分布式缓存Redis-数据管理与性能提升之道
redis·分布式·缓存
minihuabei8 小时前
linux centos 安装redis
linux·redis·centos
monkey_meng10 小时前
【Rust中多线程同步机制】
开发语言·redis·后端·rust
hlsd#10 小时前
go 集成go-redis 缓存操作
redis·缓存·golang
奶糖趣多多12 小时前
Redis知识点
数据库·redis·缓存