对我来说,如果主服务器死亡,从服务器中的Sentinel将简单地将从服务器晋升为主服务器。如果从服务器死亡,则无论如何都没关系,因为主服务器仍然存在。
我是否遗漏了什么?有哪些缺点?
为了减少延迟,我更喜欢让Sentinel与主/从服务器位于同一物理服务器上。
首先,Sentinel不是Redis的负载均衡器或代理。
其次,并非所有故障都会导致主机死机。有时服务器会短暂挂起,有时网络电缆会被拔掉等。因此,在同一主机上运行Redis实例和Sentinel并不是一个好的实践。如果您正在使用Sentinel来管理故障转移,则除Redis主节点和从节点之外的其他节点上至少需要运行三个哨兵。
Sentinel使用仲裁机制对故障转移和从属进行投票。如果少于两个Sentinel,则存在分裂大脑的风险,即两个或多个Redis服务器认为它们是主服务器。
假设您运行两个服务器并在每台服务器上运行sentinel。如果您失去了一个服务器,则丢失了可靠的故障转移功能。
客户端仅连接到Sentinel以获取当前主连接信息。每当客户端失去连接性时,它们会重复此过程。Sentinel不是Redis的代理——Redis的命令直接发送到Redis中。
少于三个哨兵运行Sentinel的唯一可靠原因是用于服务发现,这意味着不将其用于故障转移管理。
考虑两个主机的情况:
Host A: redis master + sentinel 1 (Quorum 1)
Host B: redis slave + sentinel 2 (Quorum 1)
如果在这种情况下,主机B暂时失去与主机A的网络连接,那么主机B将会晋升为主服务器。现在你有:Host A: redis master + sentinel 1 (Quorum 1)
Host B: redis master + sentinel 2 (Quorum 1)
连接到Sentinel 2的任何客户端都会被告知Host B是主节点,而连接到Sentinel 1的客户端将被告知Host A是主节点(如果您将Sentinels置于负载均衡器后,则表示一半的客户端)。
因此,为了获得最小可接受的可靠故障转移管理,您需要运行:
Host A: Redis master
Host B: Redis Slave
Host C: Sentinel 1
Host D: Sentinel 2
Host E: Sentinel 2
您的客户端连接到哨兵并获取Redis实例(按名称)的当前主服务器,然后连接到它。如果主服务器挂了,则客户端应该断开连接,然后再次连接到哨兵并获取新信息。
每个客户端库处理这种情况的能力取决于该库的特性。
理想情况下,主机C、D和E要么位于从Redis连接的同一主机上(即客户端主机),要么代表对它们进行良好抽样的主机。这里的主要推动力是确保您从需要连接到Redis的位置进行检查。如果无法实现这一点,请将它们放置在与客户端相同的数据中心/机架/区域。
如果您希望客户端与负载均衡器通信,请尽可能在这些LB节点上放置哨兵,并根据需要添加其他非LB主机以获取大于2个奇数哨兵。唯一的例外是如果您的客户端主机是动态的,例如它们根据流量进行扩展或缩小。在这种情况下,您必须在非客户端和非Redis服务器主机上运行哨兵。
请注意,如果您这样做,则需要编写一个守护程序,用于监视哨兵PUBSUB通道以更新LB的主切换事件,并配置它仅与当前主服务器通信(永远不要尝试与两者通信)。这需要更多的工作,但确实使客户端透明地使用哨兵-客户端只需知道与LB IP / Port通信即可。
(参见:http://redis.io/topics/sentinel)配置提供者。哨兵作为客户端服务发现的权威来源:客户端连接到哨兵以请求给定服务的当前Redis主服务器的地址。如果发生故障转移,哨兵将报告新地址。
这绝对不是一个推荐的方法。
Redis Sentinel文档很好地解释了权衡。希望这可以帮到你。 https://redis.io/topics/sentinel#example-sentinel-deployments