Redis Sentinel(哨兵) 文档

Redis Sentinel(哨兵) 文档

Redis Sentinel提供了 redis 的高可用方案。即你可以使用 Sentinel 实施一个 redis 部署从而在一些灾难发生的时候不用人为地进行故障转移(failover)。

Redis Sentinel还提供了一些相关的能力如:监控、通知、作为客户端的配置供给者。以下是 Sentinel 的所有能力的一个概述:

  • **监控(Monitoring)。**Sentinel 周期地检查你的主从(master and replicas)实例是否在正常地运行。
  • **通知(Notification)。**当某个被监控的 redis 实例发生异常的时候,Sentinel 可以通过一个 API 通知系统管理员或者其他计算机程序。
  • **自动故障转移(Automatic failover)。**当一个主节点不能正常工作的时候,Sentinel 会开始一个故障转移处理:将一个从节点提升为主节点,其他从节点被指令复制新的主节点,那些正在连接着 redis 服务的程序将被通知连接新的主节点。
  • **配置供给者(Configuration provider)。**Sentinel 作为客户端的服务发现中心:客户端连接到 Sentinels 以获取当前可用的 redis 主节点的地址。如果一个故障转移发生,Sentinels 会返回新的地址。

天然支持分布式的 Sentinel

Redis Sentinel 是一个分布式系统:

Sentinel 本身的设计出发点就是有多个 Sentinel 进程同时在合作运行的。以下是有多个 Sentinel 实例进行合作的优点:

  1. 当有多个 Sentinels 同时认为一个主节点不再可用的时候才会认为一个故障发生了。降低误报的可能性。
  2. 即使有一些 Sentinel 进程出现故障 Sentinel 也能正常工作,提高系统的健壮性。毕竟,拥有故障转移系统本身就是一个单点故障,这没有任何乐趣?(这句翻译软件翻的,看不太懂:There is no fun in having a failover system which is itself a single point of failure, after all.)

所有的 Sentinel 节点、Redis 实例(所有主从节点)以及那些连接着 Sentinel 和 Redis 的客户端,也是一个拥有特定属性的大分布式系统。本文档将从一些为了理解 Sentinel 的基本属性而必要的基础信息,到那些为了深入理解 Sentinel 工作机制的更复杂的信息(非必要),渐进地对一些概念进行介绍。

快速开始

获取 Sentinel

Sentinel 的当前版本是 Sentinel 2。它使用了更强大、易于预测的算法对 Sentinel 的原始版本进行了重写(本文档将会进行介绍)。

它的稳定版本从 Redis 2.8 开始提供。

新的开发在unstable(不稳定)分支中开发,新特性一旦被认为是稳定的将会被移到最新的稳定分支中。Redis Sentinel 版本1,从 Redis 2.6开始发布,现在已经被废弃,不建议使用。

运行 Sentinel

如果你正在使用可运行的redis-sentinel程序(或者你有一个可运行redis-server程序的软链接),你可以使用以下命令来运行 Sentinel:

redis-sentinel /path/to/sentinel.conf

或者你可以直接使用redis-server 可执行程序以 Sentinel 的模式启动:

redis-server /path/to/sentinel.conf --sentinel

以上的两种方式其实工作机制是一样的。

当要启动 Sentinel 的时候一定要指定一个配置文件,因为系统在重启时需要将当时的系统状态进行保存以及重载的时候使用这个配置文件。如果没有指定配置文件或者文件路径不可写,Sentinel 会拒绝启动。

Sentinels 默认监听 TCP 26379 端口,所以为了 Sentinels 正常工作,你的服务器的 26379 端口一定要打开以接收其他 Sentinel 实例的连接。(可以修改?)否则 Sentinels 无法沟通,无法投票,故而故障转移将无法进行。

部署 Sentinel 须知

  1. 你至少需要3个 Sentinel 实例才会使得部署具备健壮性。
  2. 这3个 Sentinel 实例的部署位置如服务器或者虚拟机应该保证它们的故障不会互相影响。例如不同的物理机或者运行在不同可用分区上的虚拟机。
  3. Sentinel+Redis分布式系统并不能保证在故障期间保留已确认的写入,因为Redis使用异步复制。然而有一些部署Sentinel的方法,使得丢失写入的窗口限制在某些时刻,同时还有其他不太安全的部署方式。
  4. 你的客户端需要支持 Sentinel。受欢迎的客户端的库对 Sentinel 进行了支持,但不是所有都支持。
  5. 你需要在开发环境中不时地测试你的 HA (高可用 High Availability)配置(如果允许的话,尽量在生产环境也要测试)是否可行,不然无法保证该配置是否安全。你可能只有在为时已晚的时候才发现配置错误(凌晨3点你的主节点宕掉了)
  6. Sentinel、Docker、或者其他形式的 NAT(Network Address Translation) 或者端口映射(Port Mapping)同时使用的时候需要注意:Docker 使用了端口映射,阻断了 Sentinel 自动发现其他 Sentinel 进程和主节点的从节点们。请参考下面的关于 Sentinel 和 Dcoker 的章节。

配置 Sentinel

Redis 源码发行版包含一个名为sentinel.conf的文件,它是一个带有解释的配置文件示例,你可以使用它来配置 Sentinel。一个典型的最小的配置文件如下所示:

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000
sentinel failover-timeout mymaster 180000
sentinel parallel-syncs mymaster 1

sentinel monitor resque 192.168.1.3 6380 4
sentinel down-after-milliseconds resque 10000
sentinel failover-timeout resque 180000
sentinel parallel-syncs resque 5

你只需要定义需要监控的 master 节点们,为每个不同的主实例 (可能拥有一些从实例)提供一个唯一的名字。你无需定义从实例,Sentinel 会根据主实例自动发现从实例。Sentinel 将会自动地在配置中更新关于从服务器的这些额外信息(为了在重启的时候保存信息)。该配置在每次故障转移中从实例提升为主实例以及每次一个新 Sentinel 进程被发现的时候都会被重写。

上面的配置示例简单地监控着两组 Redis 实例,每组由一个主实例和未知数量的从实例组成。其中一组实例被命名为mymaster,另外一组为resquesentinel monitor 语句的各个参数的意义如下所示:

sentinel monitor    

为了清晰起见,让我们逐行地来解析配置选项地意义:

第一行是用来指示 Redis 监控一个主实例,命名为mymaster,其地址为127.0.0.1,端口为6379quorum为2。除了quorum 参数之外其他都是清晰明了的:

  • quorum表示:当前 Sentinel 将一个主实例定义为故障(也称客观下线,同时每个 Sentinel 进程都有自己的一个判断主实例是否主观下线的条件) 需要quorum个 Sentines 实例同时认同该主实例已经下线的事实(即需要quorum个 Sentinels 同时主观地认为该实例已经下线,当前 Sentinel 才会认为该实例已经客观下线)。
  • 不过quorum仅仅被用来判定故障。为了实际地执行一次故障转移,其中一个 Sentinel 需要被选举成本次故障转移的领袖并被授权于执行故障转移。而这只有获得了大多数(N/2+1) Sentinel 进程的投票才会进行。

例如如果你拥有5个 Sentinel 进程, 某个主实例的quorum设置为2(So for example if you have 5 Sentinel processes, and the quorum for a given master set to the value of 2, this is what happens:):

  • 如果2个 Sentinels 同时(主观)认为该主实例已经下线,它们两个之一就会发起一次故障转移。(If two Sentinels agree at the same time about the master being unreachable, one of the two will try to start a failover. 这里应该有问题,实际上每个 Sentinel 进程对于每个主实例设置的quorum都可能不一样,而quorum是某个 Sentinel 认为某个主实例客观下线的条件,而发起故障转移的 Sentinel 应该由所有认为该实例已经客观下线的 Sentinels 中诞生。所以如果这里是将所有 Sentinel 中该主实例的quorum都设置为2,那么就应该是5个 Sentinels 之一而不是 one of two;只有当前提条件是2个 Sentinels 进程设置quorum为2这句话才成立,上面给的前提不太清晰)。
  • 如果至少总计有3个 Sentinels 可访问,该故障转移将会被授权并执行。

实际上这意味着在故障期间如果大多数的 Sentinel 进程无法通信故障转移将不会进行(也称在少数分区不会执行故障转移)。

其他 Sentinel 选项

其他的选项几乎都是这样的形式:

sentinel   

以及被用在以下场景:

  • down-after-milliseconds:当一个 Sentinel 经过了down-after-milliseconds个毫秒也无法和一个实例进行通信(无论是该实例没有恢复我们的PING命令还是回复了一个错误),该 Sentinel 就会主观地认为该实例已经下线。(之后会进入判断客观下线阶段,即向其他 Sentinels 确认它们是否也认为该实例主观下线,有quorum个 Sentinels 同意,当前 Sentinel 将会认为该实例已经客观下线)。
  • parallel-syncs:该数值表示在一次故障转移之后可以并行复制新主实例的从实例数量(即新主实例同时向多个从实例同步数据,这会产生并行复制从实例数量的带宽占用)。这个数值越小,故障转移处理完成需要的时间越长(数量为1时,表示同一时间只同步一个从实例,同步动作完全串行),但是如果从实例被配置为服务旧数据,你可能不想所有的从实例同时与主实例进行数据重同步。虽然复制过程(数据同步)几乎不会阻塞一个从实例,但是在其停止从主实例加载批量数据 (buik data) 之后的小段时间会阻塞。你可能会想限制同一时间确切地只有一个从实例无法访问,此时可以设置该选项为1。

其他选项在下面进行介绍,同时在 Redis 发行版中携带的sentinel.conf文件也进行了描述。

所有的配置参数都可以在运行时通过sentinel set命令进行修改。请参考在运行时修改 Sentinel 配置章节。

Sentinel 部署方案示例

现在你已经了解了 Sentinel 的基本信息,你可能会对于你应该将 Sentinel 进程部署在哪里、应该部署多少个 Sentinel 进程等等问题产生疑惑。本章节展示了几个部示例。我们使用 ASCII 码以图形的形式向你展示配置的样例,以下我们对一些图案进行了定义:

+--------------------+
| This is a computer |
| or VM that fails   |
| independently. We  |
| call it a "box"    |
+--------------------+

我们在盒子中写的内容正在其中运行:

+-------------------+
| Redis master M1   |
| Redis Sentinel S1 |
+-------------------+

不同的盒子使用线条进行连接,表示它们是可以通信的:

+-------------+               +-------------+
| Sentinel S1 |---------------| Sentinel S2 |
+-------------+               +-------------+

网络分区(Network partitions)以两个斜杠断开线条来表示:

+-------------+                +-------------+
| Sentinel S1 |------ // ------| Sentinel S2 |
+-------------+                +-------------+

以及:

  • Masters(主实例)被命名为 M1,M2,M3,…,Mn。
  • Replicas(从实例)被命名为 R1,R2,R3,…,Rn。
  • Sentinels 被命名为 S1,S2,S3,…,Sn。
  • Clients 被命名为 C1,C2,C3,…,Cn。
  • 当一个实例由于 Seneinel 的一系列动作发生了角色变更,我们使用中括号将其包裹起来,所以 [M1] 表示一个实例现在由于 Sentinel 的干涉称为了一个主实例。

示例1:仅部署两个 Sentinels,不要这样做!

+----+         +----+
| M1 |---------| R1 |
| S1 |         | S2 |
+----+         +----+

Configuration: quorum = 1
  • 在该配置中,如果主实例 M1 故障,在两个 Sentinels 可以通信并认为其已经客观下线(quorum被设置为1)的情况下,R1 将被提升为主实例并可以被授权进行故障转移,因为2个Sentinel 都可以进行通信(并进行故障转移领头 Sentinel 选举)。所以目前看来它是可行的,但是请看下面的描述介绍了该配置为什么不可行。
  • 如果 M1 所在的盒子故障了,当然 S1 也就故障了。运行在另外一个盒子中的 Sentinel S2将不能被授权(2/2+1=2,至少2个 Sentinel 才是"大多数")发起故障转移,所以整个系统将无法访问(无法选举出新的 master,整个 redis 系统无法提供正常服务)。

请注意多数投票对于不同的故障转移动作是必须的,并在之后会传播最新的配置到所有的 Sentinels。同时还要注意基于上面的配置,如果允许不经过多数投票的单点故障转移,将是非常危险的:

+----+           +------+
| M1 |----//-----| [M1] |
| S1 |           | S2   |
+----+           +------+

在以上的配置我们以非常对称的方式创建了两个主实例(假设 S2 可以在未经授权的情况进行故障转移)。客户端们分别向这两个主实例一直写入数据,然后在分区恢复的时候将无法判断出哪个才是主实例(以及哪边才是正确的配置)。所以为了防止永久脑裂,请至少分别在3个不同的盒子中部署3个 Sentinels。

示例2:基于3个盒子的基本配置

这是一个非常简单的配置,它拥有

在运行时修改 Sentinel 配置


   转载规则


《Redis Sentinel(哨兵) 文档》 阿钟 采用 知识共享署名 4.0 国际许可协议 进行许可。
  目录