前言
Redis 哨兵(Sentinel)的官方文档: Redis Sentinel Documentation
简而言之,哨兵机制是Redis高可用性的保障。
本文主要对该官方文档进行了翻译,同时也结合源码做了部分注解。
概述
Redis Sentinel为Redis提供高可用性。通过Sentinel可以部署一套无需人工干预,即可抵抗某些故障的高可用Redis。
Redis Sentinel还提供了一些附加任务,如监视,通知,给客户端(client)提供配置信息等。
Sentinel的完整功能列表(big picture):
- 监控。Sentinel会不断检查Redis的Master实例和Slave实例是否按预期工作。
- 通知。Sentinel可以通过API通知系统管理员或其他计算机程序,其中一个受监视的Redis实例出了问题。
- 自动故障转移。如果Master未按预期工作,则Sentinel可以启动故障转移过程,在该过程中将某个Slave升级为Master,将其他Slave的主从复制(Replication)目标修改为新的Master,并通知使用Redis应用程序要使用的新地址。
- 配置提供者。Sentinel为客户端client提供服务发现功能:client连接到Sentinels,询问当前Redis Master实例的地址。如果发生故障转移,Sentinels将报告新地址。
Sentinel的分布式性质
Redis Sentinel是一个分布式系统:
Sentinel本身设计为在有多个Sentinel进程协同合作的配置中运行。具有多个Sentinel进程进行协作的优点如下:
- 降低误报的几率:当多个Sentinel就给定的主机不再可用达成共识时,才执行故障转移。
- 避免单点故障:故障转移系统本身也可能出现单点故障,多个Sentinel进程协同运行,保证了即使不是所有的Sentinel进程都在工作,Sentinel仍能正常工作,从而使系统能够应对故障。
Sentinels,Redis实例(Master和Slave)以及连接到Sentinel和Redis的客户端的总和也是具有特定属性的大型分布式系统。在本文档中,将逐步介绍各个概念,先介绍基本信息,以便理解Sentinel的基本特性,再介绍Sentinel的工作原理(可选读)。
Quici Start
获取Sentinel
Sentinel的当前版本为Sentinel 2。它对Sentinel初版实现进行了重构,使用了更强大且更易于预测的算法(会在本文档中进行说明)。
自Redis 2.8之后的版本中,都已包含稳定版本的Redis Sentinel。
Redis Sentinel的不稳定分支中进行着迭代开发,一旦新功能稳定,便会立即合并回最新的稳定分支。
Redis 2.6随附的Redis Sentinel版本1已被弃用,不应使用。
运行Sentinel
有两种方法启动Sentinel:
- 使用
redis-sentinel
(实际上是一个名为redis-sentinel,指向redis-server的软连接):
1 | redis-sentinel /path/to/sentinel.conf |
- 直接使用
redis-server
以Sentinel模式启动:
1 | redis-server /path/to/sentinel.conf --sentinel |
两种方法是等效的。
但是,在运行Sentinel时必须使用配置文件,因为系统将使用此文件来保存当前状态,以便在重启时重新加载。如果未提供配置文件或配置文件路径不可写,Sentinel会拒绝启动。
Sentinels默认情况下会监听TCP端口26379的连接,因此,要使Sentinels正常工作,必须打开服务器的端口26379,以接收来自其他Sentinel实例的连接。否则,Sentinels无法讨论也不能就该做什么达成共识,因此将永远不会执行故障转移。
译者注:
从源码 server.c 里可以看到,判断是否以哨兵模式启动的条件:
1 | /* Returns 1 if there is --sentinel among the arguments or if |
如果执行的文件名包含”redis-sentinel”,或者执行参数中有”–sentinel”,就以哨兵模式启动。
部署前有关Sentinel的基本知识
- 一个健壮的部署至少需要三个Sentinel实例。
- 应将三个Sentinel实例放置到独立计算机或虚拟机中(不会同时发生故障),例如在不同的可用区域上执行的不同物理服务器或虚拟机。
- 由于Redis使用异步复制,因此Sentinel + Redis分布式系统不能保证在故障期间保留已确认的写入。但是,部署Sentinel时可以采取一些方法,使得数据写入丢失窗口仅限于某些时刻。还有其他一些不太安全的方法来部署它。
- 客户端需要Sentinel支持。并非所有的流行客户端库都具有Sentinel支持。
- 如果您不在开发环境中不时进行测试,则没有安全的HA设置,如果可以,则在生产环境中甚至可以更好地进行测试。您可能有一个错误的配置,只有在为时已晚时(主服务器停止工作的凌晨3点),该错误才会变得明显。
- Sentinel,Docker或其他形式的网络地址转换或端口映射应格外小心:Docker执行端口重新映射,会破坏Sentinel对其他Sentinel进程的自动发现以及主副本的列表。有关更多信息,请参阅本文档后面有关Sentinel和Docker的部分。
配置前哨
Redis源码目录内包含一个名为sentinel.conf
的文件 ,该文件是一个示例配置文件,可用于配置Sentinel。如下所示的是典型的最小配置文件:
1 | sentinel monitor mymaster 127.0.0.1 6379 2 |
上面的示例中监视了两组Redis实例,每个实例由一个master和未定义数量的slave组成。一组实例名为mymaster
,另一组名为resque
。
配置中只需要指定要监视的master,无需指定slave,slave是自动发现的。Sentinel会将slave的其他信息自动更新进配置文件中(以便在重新启动时保留该信息)。当在故障转移期间将slave提升为master时,以及每次发现新的Sentinel时,都会重写配置。
配置需要监控的Master
sentinel monitor
语句参数的含义如下:
1 | sentinel monitor <master-group-name> <ip> <port> <quorum> |
各配置选项的含义:
第一行用于告诉Redis监视一个名为 mymaster 的master,其地址为127.0.0.1,端口为6379,仲裁数为2。其中 quorum 表示仲裁数,其意义为:
- 当判定master不可用的Sentinel进程数量 ≥ quorum时,才能真正标记master不可用,并最终开始故障转移过程。
- 但是,quorum仅用于检测故障。为了实际执行故障转移,需要将其中一名Sentinels选为故障转移的负责人,并授权其进行操作。必须有超过半数的Sentinel进程投票,才会进行故障转移。
例如,有5个Sentinel进程,并且给定主服务器的仲裁设置为2,则将发生以下情况:
- 如果有两个Sentinel同时认为master不可访问,则这两个Sentinel中的一个将尝试启动故障转移。
- 如果总共至少有三个Sentinel可以访问,则故障转移将被授权并实际上开始。
这意味着在发生故障期间,如果超过半数的Sentinel进程无法进行对话,Sentinel不会启动故障转移(即:不过半数无故障转移)。
其他配置项
其他配置项几乎总是采用以下形式:
1 | sentinel <option_name> <master_name> <option_value> |
配置项:
down-after-milliseconds
不可用时间,以毫秒为单位。是指Sentinel无法访问某实例(实例未答复PING或答复错误),持续所指定的时间后,认为实例不可用。parallel-syncs
配置了在故障转移时,同时和新master的同步数据的slave数量。数字越小,完成故障转移过程所花费的时间越多;但越大就意味着越多的slave因为复制而不可用(尽管slave在复制过程中绝大部分时间是非阻塞的,但仍会在载入大量数据时对外停止服务一小段时间)。将此选项设置为值1,可以确保一次只有一个副本无法访问。
其他选项在本文档的其余部分中进行了描述,并在sentinel.conf
Redis分发随附的示例文件中进行了说明。
使用SENTINEL SET
命令,可以在运行时修改所有配置参数。有关更多信息,请参见“在运行时重新配置Sentinel”部分。