Sentinel 客户端规范

如何为 Redis Sentinel 构建客户端

Redis Sentinel 是 Redis 实例的监控解决方案,用于处理 Redis 主节点和服务发现的自动故障转移(谁是当前的 master 的实例组?由于 Sentinel 都负责 用于在故障转移期间重新配置实例,并将配置提供给 连接到 Redis 主节点或副本的客户端,客户端需要具有 显式支持 Redis Sentinel。

本文档面向希望在客户端实施中支持 Sentinel 的 Redis 客户端开发人员,其目标如下:

  • 通过 Sentinel 自动配置客户端。
  • 提高了 Redis Sentinel 自动故障转移的安全性。

有关 Redis Sentinel 工作原理的详细信息,请查看 Redis 文档,因为本文档仅包含 Redis 客户端开发人员所需的信息,希望读者熟悉 Redis Sentinel 的工作方式。

通过 Sentinel 发现 Redis 服务

Redis Sentinel 使用类似于 “stats” 或 “cache” 的名称来识别每个 master。 每个名称实际上都标识了一组实例,这些实例由一个 master 组成 以及可变数量的副本。

在发生自动故障转移、手动触发的故障转移(例如,为了升级 Redis 实例)等事件后,网络内用于特定目的的 Redis 主节点的地址可能会发生变化。

通常,Redis 客户端具有某种硬编码配置,该配置将网络中 Redis 主实例的地址指定为 IP 地址和端口号。但是,如果主地址发生变化,则需要在每个客户端中进行手动干预。

支持 Sentinel 的 Redis 客户端可以使用 Redis Sentinel 从主服务器名称中自动发现 Redis 主服务器的地址。因此,支持 Sentinel 的客户端应该能够选择性地将 IP 地址和端口作为输入,而不是硬编码的 IP 地址和端口:

  • 指向已知 Sentinel 实例的 ip:port 对列表。
  • 服务的名称,如 “cache” 或 “timelines”。

这是客户端应遵循的过程,以便从 Sentinel 列表和服务名称开始获取主地址。

第 1 步:连接到第一个 Sentinel

客户端应迭代 Sentinel 地址列表。对于每个地址,它应该尝试连接到 Sentinel,使用较短的超时时间(大约几百毫秒)。出现错误或超时时,应尝试下一个 Sentinel 地址。

如果尝试了所有 Sentinel 地址均未成功,则应向客户端返回错误。

回复客户端请求的第一个 Sentinel 应放在列表的开头,以便在下次重新连接时,我们将首先尝试在上一次连接尝试中可访问的 Sentinel,从而最大限度地减少延迟。

第 2 步:询问主地址

与 Sentinel 建立连接后,客户端应重试以在 Sentinel 上执行以下命令:

SENTINEL get-master-addr-by-name master-name

其中 master-name 应替换为用户指定的实际服务名称。

此调用的结果可以是以下两个回复之一:

  • 一个 ip:port 对。
  • 空回复。这意味着 Sentinel 不知道这个 master。

如果收到 ip:port 对,则应使用此地址连接到 Redis 主节点。否则,如果收到 null 回复,则客户端应尝试列表中的下一个 Sentinel。

步骤 3:在目标实例中调用 ROLE 命令

一旦客户端发现 master 实例的地址,它应该 尝试与 master 建立连接,并调用ROLE命令 验证实例的角色是否确实是 Master。

如果ROLE命令不可用(在 Redis 2.8.12 中引入),客户端可以求助于INFO replication命令解析role:字段。

如果实例不是预期的主实例,则客户端应等待一小段时间(几百毫秒),并应从步骤 1 开始重试。

处理重新连接

将服务名称解析为主地址并与 Redis 主实例建立连接后,每次需要重新连接时,客户端都应使用从步骤 1 重新启动的 Sentinels 再次解析地址。例如,在以下情况下,Sentinel 应再次联系:

  • 如果客户端在超时或套接字错误后重新连接。
  • 如果客户端由于用户显式关闭或重新连接而重新连接。

在上述情况以及客户端丢失与 Redis 服务器的连接的任何其他情况下,客户端应再次解析主地址。

Sentinel 故障转移断开连接

从 Redis 2.8.12 开始,当 Redis Sentinel 更改 一个实例,例如将副本提升为主服务器,将主服务器降级为 在故障转移后复制到新的 Master,或者只是更改 Master address 时,它会发送一个CLIENT KILL type normal命令添加到实例中,以确保所有客户端都已断开连接 从重新配置的实例中。这将强制客户端解析 master 地址。

如果客户端将联系 Sentinel 并提供尚未更新的信息,则通过ROLE命令将失败,从而允许客户端检测到所联系的 Sentinel 提供了过时的信息,并将重试。

注意:在客户端联系过时的 Sentinel 实例的同时,过时的主服务器可能会恢复在线状态,因此客户端可能会与过时的主服务器连接,但 ROLE 输出将匹配。但是,当主服务器再次返回时,Sentinel 将尝试将其降级为副本,从而触发新的断开连接。同样的推理也适用于连接到过时的副本,这些副本将被重新配置为使用不同的 master 进行复制。

连接到副本

有时,客户端对连接到副本感兴趣,例如,为了扩展读取请求。此协议支持通过稍微修改步骤 2 来连接到副本。而不是调用以下命令:

SENTINEL get-master-addr-by-name master-name

客户端应改为调用:

SENTINEL replicas master-name

为了检索副本实例的列表。

对称地,客户端应使用ROLE命令,该命令的 instance 实际上是一个副本,以避免使用 大师。

连接池

对于实现连接池的客户端,在重新连接单个连接时,应再次联系 Sentinel,如果主地址发生更改,则应关闭所有现有连接并连接到新地址。

错误报告

如果出现错误,客户端应正确地将信息返回给用户。具体说来:

  • 如果无法联系 Sentinel(因此客户端永远无法获得对SENTINEL get-master-addr-by-name),应返回一个错误,明确指出 Redis Sentinel 无法访问。
  • 如果池中的所有 Sentinel 都使用 null 回复进行回复,则应通知用户 Sentinels 不知道此主名称。

Sentinels 列表自动刷新

(可选)一旦成功回复get-master-addr-by-name收到,则客户端可以按照以下过程更新其内部 Sentinel 节点列表:

  • 使用命令获取此主服务器的其他 Sentinel 的列表SENTINEL sentinels <master-name>.
  • 在列表末尾添加列表中尚不存在的每个 ip:port 对。

客户端不需要能够使列表持久化,更新其自己的配置。升级 Sentinel 列表的内存中表示的功能对于提高可靠性已经很有用。

订阅 Sentinel 事件以提高响应能力

Sentinel 文档展示了客户端如何连接到 Sentinel 实例使用 Pub/Sub 订阅 Redis 实例配置。

此机制可用于加速客户端的重新配置, 也就是说,客户端可以监听 Pub/Sub 以了解何时进行配置 更改是为了运行此处解释的三步协议 document 来解析新的 Redis 主(或副本)地址。

但是,通过 Pub/Sub 接收的更新消息不应替换 上述过程,因为不能保证客户端能够 接收所有更新消息。

其他信息:

有关更多信息或讨论本指南的特定方面,请向 Redis Google 群组发送消息。

为本页评分
返回顶部 ↑