一切的恐惧,且来源于火力不足
假如有人问题如下问题,你能回答上来吗?如果你能回答上来,那么你可以跳过本文。如何回答不了,本文将给你答案。
Sentinel 提供的功能:
Redis 源分配包含一个名为的文件,该文件是一个自记录的示例配置文件,可用于配置 Sentinel,但是典型的最小配置文件如下所示 以后:sentinel.conf
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将更新使用有关副本的其他信息自动配置(在以便在重新启动时保留信息)。配置是在故障转移期间,每次将副本提升为主副本时,也会重写并且每次发现新的哨兵时。
上面的示例配置基本上监控了两组Redis实例,每个实例由一个主实例和未定义数量的副本组成。一组实例称为,另一组实例称为。mymasterresque
语句参数的含义如下:
sentinel monitor <master-name> <ip> <port> <quorum>
第一行用于告诉Redis监视一个名为mymaster的master,即位于地址127.0.0.1和端口6379,仲裁为2。万事很明显,但仲裁参数:
仲裁是需要就无法访问主服务器这一事实达成一致的哨兵数量,以便真正将主服务器标记为失败,并在可能的情况下最终启动故障转移过程。
但是,仲裁仅用于检测故障。为了实际执行故障转移,需要将其中一个哨兵选为故障转移的领导者,并被授权继续。这只有在大多数Sentinel进程的投票中才会发生。
例如,如果您有5个Sentinel进程,并且给定的仲裁master设置为值2,这是发生的情况:
如果两个哨兵同时同意无法访问主节点,则两个哨兵中的一个将尝试启动故障转移。
如果总共至少有三个哨兵可访问,则故障转移将获得授权并实际启动。
实际上,这意味着在故障期间,如果大多数Sentinel进程无法通信(即少数分区中没有故障转移),则Sentinel永远不会启动故障转移
您可以运行 Sentinel 使用以下命令行:
redis-sentinel /path/to/sentinel.conf
否则,您可以直接使用edis-server启动它哨兵模式:
redis-server /path/to/sentinel.conf --sentinel
默认情况下,哨兵运行侦听与TCP端口26379的连接,因此要使Sentinels正常工作,必须打开服务器的端口26379才能接收来自其他Sentinel实例的IP地址的连接。否则,哨兵无法交谈,也无法就该做什么达成一致,因此会进行故障转移永远不会执行。
Sentinel本身被设计为在有多个Sentinel进程协同的配置中运行。让多个Sentinel进程协同工作的优势如下:
当多个Sentinel同意给定主节点不再可用时,将执行故障检测。这降低了误报的可能性。
即使并非所有Sentinel进程都正常工作,Sentinel也能正常工作,从而使系统能够抵御故障。毕竟,拥有一个本身就是单点故障的故障转移系统并没有什么乐趣。
使用Sentinel时,最明显的事情就是检查主控监控良好:
$ redis-cli -p 5000
127.0.0.1:5000> sentinel master mymaster
1) "name"
2) "mymaster"
3) "ip"
4) "127.0.0.1"
5) "port"
6) "6379"
7) "runid"
8) "953ae6a589449c13ddefaee3538d356d287f509b"
9) "flags"
10) "master"
11) "link-pending-commands"
12) "0"
13) "link-refcount"
14) "1"
15) "last-ping-sent"
16) "0"
17) "last-ok-ping-reply"
18) "735"
19) "last-ping-reply"
20) "735"
21) "down-after-milliseconds"
22) "5000"
23) "info-refresh"
24) "126"
25) "role-reported"
26) "master"
27) "role-reported-time"
28) "532439"
29) "config-epoch"
30) "1"
31) "num-slaves"
32) "1"
33) "num-other-sentinels"
34) "2"
35) "quorum"
36) "2"
37) "failover-timeout"
38) "60000"
39) "parallel-syncs"
40) "1"
它打印了有关主站的许多信息。有我们特别感兴趣的一些:
# 提供有关连接到主人
SENTINEL replicas mymaster
# SENTINEL sentinels mymaster
SENTINEL sentinels mymaster
Sentinel需要充当连接一组主服务器和副本的客户端,达到故障转移和重新配置的目的。通过以下命令实现:
127.0.0.1:5000> SENTINEL get-master-addr-by-name mymaster
1) "127.0.0.1"
2) "6379"
将新的Sentinel添加到您的部署是一个简单的过程,因为由Sentinel实现的自动发现机制。您需要做的就是启动配置为监视当前活动主节点的新Sentinel。在10秒内,哨兵将获得其他哨兵的列表,并且附加到主服务器的复制副本集。
如果需要一次添加多个哨兵,建议添加一个接一个,等待所有其他哨兵已经知道在添加下一个之前,关于第一个。这很有用,以便仍然保证多数只能在分区的一侧实现,在添加新哨兵的过程中应该发生故障。
移除哨兵有点复杂:哨兵永远不会忘记已经看到的东西哨兵,即使他们长时间无法联系到,因为我们没有想要动态更改授权故障转移所需的多数,并且创建新的配置编号。所以为了删除哨兵在没有网络分区的情况下,应执行以下步骤:
SENTINEL RESET **
SENTINEL MASTER mastername
Redis Sentinel 有两种不同的宕机概念,一种称为 主观下降条件 (SDOWN),是 给定 Sentinel 实例的本地。另一个称为客观宕机条件 (ODOWN),当足够多的哨兵(至少 配置为受监控主站参数的编号)具有 SDOWN 条件,并使用 命令。quorumSENTINEL is-master-down-by-addr
哨兵与其他哨兵保持联系,以便相互联系检查彼此的可用性,并交换消息。然而,你不需要在每个Sentinel中配置其他Sentinel地址的列表实例,因为Sentinel使用Redis实例Pub/Sub功能为了发现监视同一主站的其他哨兵和副本。
此功能是通过向名为的通道发送hello消息来实现的。sentinel:hello
同样,您也不需要配置附加的副本列表到主节点,因为Sentinel会自动发现查询Redis的此列表。
每个Sentinel每两秒向每个受监控的主通道和副本Pub/Sub通道发布一条消息,使用ip、port、runid宣布其存在。sentinel:hello
每个Sentinel都订阅了每个主节点和副本的Pub/Sub通道,寻找未知的哨兵。当检测到新的哨兵时,它们将被添加为该主节点的哨兵。sentinel:hello
Hello消息还包括主设备的完整当前配置。如果接收Sentinel的给定主节点的配置早于接收的配置,则它会立即更新到新配置。
在将新哨兵添加到主节点之前,哨兵总是会检查是否已经存在具有相同符文标识或相同地址(ip和端口对)的哨兵。在这种情况下,将删除所有匹配的哨兵,并添加新的哨兵。
Sentinel监控的每个主节点都与配置的仲裁相关联。它指定Sentinel进程数需要就主站的无法访问性或错误条件达成一致顺序触发故障转移。
但是,在触发故障转移后,为了实际执行故障转移,至少大多数哨兵必须授权哨兵故障转移。Sentinel从不在分区中执行故障转移,其中少数哨兵存在。
其中有一些概念要弄清楚:
这意味着仲裁可用于通过两种方式调整Sentinel:
哨兵需要获得多数人的授权才能开始故障转移有几个重要原因:
当Sentinel获得授权时,它将获得它正在故障转移的主节点的唯一配置周期。这是一个数字,用于在故障转移完成后对新配置进行版本控制。因为大多数人都同意将给定版本分配给给定的Sentinel,所以没有其他Sentinel能够使用它。这意味着每个故障转移的每个配置都使用唯一的版本进行版本控制。我们将了解为什么这如此重要。
此外,哨兵有一个规则:如果一个哨兵投票给另一个哨兵支持给定主节点的故障转移,它将等待一段时间来尝试再次对同一主节点进行故障转移。此延迟是您可以在中配置的。这意味着Sentinel不会尝试同时对同一个主服务器进行故障转移,第一个请求获得授权的人将尝试,如果失败,另一个将在一段时间后尝试,依此类推。2 * failover-timeoutsentinel.conf
RedisSentinel保证了活动属性,即如果大多数Sentinel能够通信,则最终将授权在主节点关闭时进行故障转移。
RedisSentinel还保证了每个Sentinel将使用不同的配置周期对同一主节点进行故障转移的安全属性。
一旦Sentinel能够成功故障转移主节点,它将开始广播新配置,以便其他Sentinel更新其有关给定主节点的信息。
要使故障转移被视为成功,它要求Sentinel能够将命令发送到选定的副本,并且稍后在主副本的INFO输出中观察到切换到主副本。REPLICAOFNOONE
此时,即使正在进行副本的重新配置,故障转移也被视为成功,并且所有哨兵都需要开始报告新配置。
新配置的传播方式是我们需要每个Sentinel故障切换使用不同的版本号(配置纪元)进行授权。
每个Sentinel都使用RedisPub/Sub消息在主节点和所有副本中持续广播其主节点配置版本。同时,所有哨兵都在等待消息,看看配置是什么由其他哨兵宣传。
配置在Pub/Sub频道中广播。sentinel:hello
由于每个配置都有不同的版本号,因此版本越大总是胜过较小的版本。
因此,例如,master的配置以所有相信主人的哨兵在192.168.1.50:6379。此配置具有版本1。一段时间后,Sentinel被授权使用版本2进行故障转移。如果故障转移成功,它将开始广播新配置,例如版本2的192.168.1.50:9000。所有其他实例将看到此配置,并相应地更新其配置,因为新配置具有更大的版本。mymaster
这意味着Sentinel保证了第二个存活属性:一组能够通信的哨兵将全部收敛到具有更高版本号的相同配置。
基本上,如果网络是分区的,每个分区都会收敛到更高的分区本地配置。在没有分区的特殊情况下,有一个分区,每个Sentinel都会同意配置。
RedisSentinel使用“stats”或“cache”等名称标识每个主节点。每个名称实际上都标识了一组实例,由一个主实例组成以及可变数量的副本。
客户端应循环访问Sentinel地址列表。对于每个地址,它都应该尝试连接到Sentinel,使用短超时(大约几百毫秒)。出现错误或超时时,应尝试下一个Sentinel地址。
如果尝试了所有Sentinel地址均未成功,则应向客户端返回错误。
应将第一个回复客户端请求的Sentinel放在列表的开头,以便在下次重新连接时,我们将首先尝试在上一次连接尝试中可访问的Sentinel,从而最大程度地减少延迟。
与Sentinel建立连接后,客户端应重试在Sentinel上执行以下命令:
SENTINEL get-master-addr-by-name master-name
其中master-name应替换为用户指定的实际服务名称。
此调用的结果可以是以下两个回复之一:
一个ip:port对。
空回复。这意味着Sentinel不认识这个主节点。
如果收到ip:port对,则应使用此地址连接到Redis主节点。否则,如果收到null回复,客户端应尝试列表中的下一个Sentinel。
一旦客户端发现了主实例的地址,它应该尝试与主服务器连接,并按顺序调用ROLE命令验证实例的角色是否真的是主实例。
如果ROLE命令不可用(它是在Redis2.8.12中引入的),客户端可能会求助于解析输出字段的命令。INFO replicationrole
:
如果实例不是预期的主实例,则客户端应等待一小段时间(几百毫秒),并应从步骤1开始重试。
将服务名称解析为主地址并与Redis主实例建立连接后,每次需要重新连接时,客户端都应使用从步骤1重新启动的Sentinel再次解析地址。例如,在以下情况下,Sentinel应再次联系: