redis技术分享——(2)




2018-07-03

blog_main_img

Redis Sentinel 是 Redis 官方提供的高可用方案。它主要用于监控 Redis 主从集群,并在主节点故障时自动完成故障转移,把某个从节点提升为新的主节点。

Redis Sentinel 是 Redis 官方提供的高可用方案。它主要用于监控 Redis 主从集群,并在主节点故障时自动完成故障转移,把某个从节点提升为新的主节点。

如果只是单机 Redis,一旦 Redis 进程宕机、机器故障或网络异常,业务就会直接受到影响。Sentinel 的价值就在于:它可以让 Redis 主从架构具备自动恢复能力。

本文主要围绕 Redis Sentinel 的核心概念、部署方式、配置示例、故障转移流程和客户端使用方式来展开。

一、Sentinel 解决什么问题

在没有 Sentinel 的情况下,一个常见的 Redis 主从架构可能是这样:

client
  |
master
  |
replica

主节点负责写入,从节点负责复制主节点数据。

但问题是:如果 master 宕机了,replica 不会自动变成 master。此时需要人工介入:

  1. 判断 master 是否真的故障
  2. 从 replica 中选择一个节点
  3. 执行 SLAVEOF NO ONEREPLICAOF NO ONE
  4. 修改其他从节点复制新的 master
  5. 修改业务连接地址

这些操作如果靠人工处理,恢复时间长,而且容易出错。

Sentinel 就是用来自动完成这些事情的。

它主要提供三类能力:

  • 监控:检查 Redis 主节点和从节点是否正常
  • 通知:发现故障时可以通知管理员或其他系统
  • 自动故障转移:主节点故障时自动选举新的主节点

二、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 节点故障时,有两个重要概念:

1. 主观下线 SDOWN

某一个 Sentinel 认为 Redis 节点不可用,称为主观下线。

例如 Sentinel A 连不上 master,它会认为 master 进入 SDOWN 状态。

但这只是一个 Sentinel 的判断,可能是网络抖动,也可能是 Sentinel A 自己的问题。

2. 客观下线 ODOWN

多个 Sentinel 都认为 master 不可用,并且达到配置中的 quorum 数量,才会认为 master 客观下线。

客观下线之后,Sentinel 才会开始故障转移。

例如配置:

sentinel monitor mymaster 127.0.0.1 6379 2

最后的 2 就是 quorum,表示至少 2 个 Sentinel 认为 master 下线,才会进入客观下线。

四、Redis 主从配置示例

假设有 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

五、Sentinel 配置示例

假设部署 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 状态

连接 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 大致会经历以下过程:

  1. 某个 Sentinel 发现 master 无法响应,标记为主观下线
  2. Sentinel 向其他 Sentinel 询问 master 状态
  3. 达到 quorum 后,master 被标记为客观下线
  4. Sentinel 之间选举出一个 leader
  5. leader 从 replica 中选择一个最合适的节点作为新 master
  6. 新 master 执行 REPLICAOF NO ONE
  7. 其他 replica 改为复制新的 master
  8. 旧 master 恢复后,会被改造成新 master 的 replica

整个过程对业务来说是自动完成的,但客户端必须正确接入 Sentinel,才能在主节点切换后找到新的 master。

九、Sentinel 如何选择新的 Master

Sentinel 选择新 master 时,会参考多个因素:

  • replica 是否在线
  • replica 和旧 master 的复制偏移量差距
  • replica 的优先级
  • replica 的运行 ID

可以通过配置控制某个 replica 是否优先被提升:

replica-priority 100

值越小优先级越高。

如果设置为 0,表示这个 replica 永远不会被提升为 master:

replica-priority 0

这个配置适合只做备份、不希望承担写流量的从节点。

十、客户端如何连接 Sentinel

使用 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 Boot 示例

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 密码。

十一、带密码的 Sentinel 配置

如果 Redis master 配置了密码:

requirepass 123456

replica 需要配置访问 master 的密码:

masterauth 123456
requirepass 123456

Sentinel 也需要知道 Redis 数据节点的密码:

sentinel auth-pass mymaster 123456

如果 Sentinel 自己也要求客户端认证,可以配置:

requirepass sentinel_password

这种情况下,客户端连接 Sentinel 时也要提供 Sentinel 密码。

十二、Docker 部署注意事项

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 返回的地址是外部客户端能够访问的地址。

十三、Sentinel 和 Cluster 的区别

Redis Sentinel 和 Redis Cluster 都能提升 Redis 可用性,但它们解决的问题不同。

方案 主要能力 是否分片 适合场景
Sentinel 主从高可用、自动故障转移 单主库高可用
Cluster 分片、高可用、自动故障转移 数据量大、需要水平扩展

如果你的数据量单机 Redis 能承载,只是需要高可用,Sentinel 就够了。

如果数据量很大,单个 Redis 节点放不下,或者写入压力需要分散到多个主节点,就应该考虑 Redis Cluster。

十四、生产环境建议

Sentinel 在生产环境中建议注意以下几点:

  • 至少部署 3 个 Sentinel 节点
  • Sentinel 尽量分布在不同机器上
  • quorum 不要设置为 1
  • 客户端必须通过 Sentinel 获取 master,不要写死 Redis master 地址
  • Redis 数据节点和 Sentinel 都要设置密码
  • 配置合理的 down-after-milliseconds,避免网络抖动导致误判
  • 开启 AOF 或 RDB,避免 Redis 重启后数据丢失
  • 监控 master 切换、复制延迟、连接数、内存使用率
  • Docker 环境要确认 announce 地址是否正确

十五、一次简单的故障演练

可以通过下面步骤验证 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 变成了 63806381,说明 Sentinel 已经完成故障转移。

再查看 replica 状态:

redis-cli -p 6380 INFO replication
redis-cli -p 6381 INFO replication

可以确认当前节点的角色是 master 还是 replica。

十六、总结

Redis Sentinel 是 Redis 主从架构下的官方高可用方案。

它的核心作用是:

  • 监控 Redis 主从节点
  • 判断 master 是否故障
  • 自动选举新的 master
  • 通知客户端当前 master 地址变化

使用 Sentinel 时,最重要的是两点:

第一,Sentinel 本身要部署多个节点,通常至少 3 个。

第二,业务客户端必须通过 Sentinel 连接 Redis,而不是写死某个 master 地址。

如果 Redis 数据量还没有大到需要分片,Sentinel 是一个相对简单、成熟、实用的高可用方案。等到单主节点容量或写入压力成为瓶颈时,再考虑 Redis Cluster 会更合适。