2018-07-03
Redis Sentinel 是 Redis 官方提供的高可用方案。它主要用于监控 Redis 主从集群,并在主节点故障时自动完成故障转移,把某个从节点提升为新的主节点。
Redis Sentinel 是 Redis 官方提供的高可用方案。它主要用于监控 Redis 主从集群,并在主节点故障时自动完成故障转移,把某个从节点提升为新的主节点。
如果只是单机 Redis,一旦 Redis 进程宕机、机器故障或网络异常,业务就会直接受到影响。Sentinel 的价值就在于:它可以让 Redis 主从架构具备自动恢复能力。
本文主要围绕 Redis Sentinel 的核心概念、部署方式、配置示例、故障转移流程和客户端使用方式来展开。
在没有 Sentinel 的情况下,一个常见的 Redis 主从架构可能是这样:
client
|
master
|
replica
主节点负责写入,从节点负责复制主节点数据。
但问题是:如果 master 宕机了,replica 不会自动变成 master。此时需要人工介入:
SLAVEOF NO ONE 或 REPLICAOF NO ONE这些操作如果靠人工处理,恢复时间长,而且容易出错。
Sentinel 就是用来自动完成这些事情的。
它主要提供三类能力:
一个典型的 Sentinel 架构如下:
sentinel-1
|
sentinel-2 --+-- sentinel-3
|
redis-master
/ \
redis-replica-1 redis-replica-2
一般建议至少部署 3 个 Sentinel 节点。
原因是 Sentinel 需要通过投票来判断主节点是否客观下线。如果只有一个 Sentinel,一旦它自身出问题,也会影响判断。3 个 Sentinel 可以避免单点问题,并且可以通过多数派完成故障确认和 leader 选举。
Sentinel 判断 Redis 节点故障时,有两个重要概念:
某一个 Sentinel 认为 Redis 节点不可用,称为主观下线。
例如 Sentinel A 连不上 master,它会认为 master 进入 SDOWN 状态。
但这只是一个 Sentinel 的判断,可能是网络抖动,也可能是 Sentinel A 自己的问题。
多个 Sentinel 都认为 master 不可用,并且达到配置中的 quorum 数量,才会认为 master 客观下线。
客观下线之后,Sentinel 才会开始故障转移。
例如配置:
sentinel monitor mymaster 127.0.0.1 6379 2
最后的 2 就是 quorum,表示至少 2 个 Sentinel 认为 master 下线,才会进入客观下线。
假设有 3 个 Redis 实例:
| 角色 | 地址 | 端口 |
|---|---|---|
| master | 127.0.0.1 | 6379 |
| replica-1 | 127.0.0.1 | 6380 |
| replica-2 | 127.0.0.1 | 6381 |
master 的配置可以比较简单:
port 6379
bind 0.0.0.0
protected-mode no
appendonly yes
replica-1 配置:
port 6380
bind 0.0.0.0
protected-mode no
appendonly yes
replicaof 127.0.0.1 6379
replica-2 配置:
port 6381
bind 0.0.0.0
protected-mode no
appendonly yes
replicaof 127.0.0.1 6379
Redis 5.0 之前常用的是:
slaveof 127.0.0.1 6379
Redis 5.0 之后推荐使用:
replicaof 127.0.0.1 6379
假设部署 3 个 Sentinel:
| Sentinel | 端口 |
|---|---|
| sentinel-1 | 26379 |
| sentinel-2 | 26380 |
| sentinel-3 | 26381 |
sentinel-1.conf:
port 26379
bind 0.0.0.0
protected-mode no
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel-2.conf:
port 26380
bind 0.0.0.0
protected-mode no
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel-3.conf:
port 26381
bind 0.0.0.0
protected-mode no
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
sentinel parallel-syncs mymaster 1
sentinel monitor mymaster 127.0.0.1 6379 2
表示 Sentinel 监控一个名为 mymaster 的 Redis 主节点,地址是 127.0.0.1:6379,quorum 是 2。
sentinel down-after-milliseconds mymaster 5000
表示 Sentinel 超过 5 秒没有收到 master 的有效响应,就会认为它主观下线。
sentinel failover-timeout mymaster 60000
表示一次故障转移的超时时间。
sentinel parallel-syncs mymaster 1
表示故障转移后,同时允许几个从节点向新的 master 同步数据。设置为 1 可以降低新 master 的压力。
启动 Redis master:
redis-server redis-6379.conf
启动两个 replica:
redis-server redis-6380.conf
redis-server redis-6381.conf
启动 Sentinel:
redis-sentinel sentinel-26379.conf
redis-sentinel sentinel-26380.conf
redis-sentinel sentinel-26381.conf
也可以使用下面这种方式启动 Sentinel:
redis-server sentinel-26379.conf --sentinel
连接 Sentinel:
redis-cli -p 26379
查看 master 信息:
SENTINEL master mymaster
查看所有被监控的 master:
SENTINEL masters
查看 replica:
SENTINEL replicas mymaster
Redis 5.0 之前命令是:
SENTINEL slaves mymaster
查看其他 Sentinel:
SENTINEL sentinels mymaster
获取当前 master 地址:
SENTINEL get-master-addr-by-name mymaster
返回结果类似:
1) "127.0.0.1"
2) "6379"
当 master 发生故障时,Sentinel 大致会经历以下过程:
REPLICAOF NO ONE整个过程对业务来说是自动完成的,但客户端必须正确接入 Sentinel,才能在主节点切换后找到新的 master。
Sentinel 选择新 master 时,会参考多个因素:
可以通过配置控制某个 replica 是否优先被提升:
replica-priority 100
值越小优先级越高。
如果设置为 0,表示这个 replica 永远不会被提升为 master:
replica-priority 0
这个配置适合只做备份、不希望承担写流量的从节点。
使用 Sentinel 后,业务代码不应该直接固定连接某个 Redis master 地址。
原因是故障转移后,master 地址可能会变化。
正确方式是让客户端连接 Sentinel,通过 master name 获取当前 master 地址。
例如 Java 中使用 Lettuce 或 Jedis 时,通常会配置:
sentinel addresses:
- 127.0.0.1:26379
- 127.0.0.1:26380
- 127.0.0.1:26381
master name: mymaster
客户端会通过 Sentinel 查询 mymaster 当前对应的 master 地址,并在故障转移后自动更新连接。
spring:
data:
redis:
sentinel:
master: mymaster
nodes:
- 127.0.0.1:26379
- 127.0.0.1:26380
- 127.0.0.1:26381
password: your_password
如果 Redis 和 Sentinel 都设置了密码,需要根据客户端版本确认密码配置项。有些客户端区分 Redis 数据节点密码和 Sentinel 密码。
如果 Redis master 配置了密码:
requirepass 123456
replica 需要配置访问 master 的密码:
masterauth 123456
requirepass 123456
Sentinel 也需要知道 Redis 数据节点的密码:
sentinel auth-pass mymaster 123456
如果 Sentinel 自己也要求客户端认证,可以配置:
requirepass sentinel_password
这种情况下,客户端连接 Sentinel 时也要提供 Sentinel 密码。
Sentinel 在 Docker 或 Kubernetes 环境中部署时,要特别注意地址通告问题。
Sentinel 会把它发现的 Redis 地址告诉客户端。如果容器内部地址、宿主机地址和客户端可访问地址不一致,客户端可能拿到一个无法连接的 IP。
常见解决方式是配置 announce:
replica-announce-ip 192.168.1.10
replica-announce-port 6380
Sentinel 也可以配置:
sentinel announce-ip 192.168.1.10
sentinel announce-port 26379
如果是在 Docker Compose 内部服务之间访问,可以优先使用服务名和容器网络。
如果是宿主机或外部服务访问,要确保 Sentinel 返回的地址是外部客户端能够访问的地址。
Redis Sentinel 和 Redis Cluster 都能提升 Redis 可用性,但它们解决的问题不同。
| 方案 | 主要能力 | 是否分片 | 适合场景 |
|---|---|---|---|
| Sentinel | 主从高可用、自动故障转移 | 否 | 单主库高可用 |
| Cluster | 分片、高可用、自动故障转移 | 是 | 数据量大、需要水平扩展 |
如果你的数据量单机 Redis 能承载,只是需要高可用,Sentinel 就够了。
如果数据量很大,单个 Redis 节点放不下,或者写入压力需要分散到多个主节点,就应该考虑 Redis Cluster。
Sentinel 在生产环境中建议注意以下几点:
down-after-milliseconds,避免网络抖动导致误判可以通过下面步骤验证 Sentinel 是否正常工作。
查看当前 master:
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
停止 master:
redis-cli -p 6379 SHUTDOWN
等待几秒后再次查看 master:
redis-cli -p 26379 SENTINEL get-master-addr-by-name mymaster
如果返回的端口从 6379 变成了 6380 或 6381,说明 Sentinel 已经完成故障转移。
再查看 replica 状态:
redis-cli -p 6380 INFO replication
redis-cli -p 6381 INFO replication
可以确认当前节点的角色是 master 还是 replica。
Redis Sentinel 是 Redis 主从架构下的官方高可用方案。
它的核心作用是:
使用 Sentinel 时,最重要的是两点:
第一,Sentinel 本身要部署多个节点,通常至少 3 个。
第二,业务客户端必须通过 Sentinel 连接 Redis,而不是写死某个 master 地址。
如果 Redis 数据量还没有大到需要分片,Sentinel 是一个相对简单、成熟、实用的高可用方案。等到单主节点容量或写入压力成为瓶颈时,再考虑 Redis Cluster 会更合适。