首先,Sentinel 不是 Redis 的负载均衡器或代理。
其次,并不是所有的失败都是宿主的死亡。有时服务器会短暂挂起,有时会拔掉网线等。因此,在与 Redis 实例相同的主机上运行 Sentinel 并不是一个好习惯。如果您使用 Sentinel 来管理故障转移,那么在 Redis 主节点和从节点之外的节点上运行的任何少于三个的哨兵都在自找麻烦。
Sentinel 使用仲裁机制对故障转移和从属设备进行投票。如果少于两个哨兵,您将面临裂脑的风险,其中两个或更多 Redis 服务器认为它们是主服务器。
想象一下您运行两台服务器并在每台服务器上运行哨兵的场景。如果您丢失一个,您将失去可靠的故障转移功能。
客户端仅连接到 Sentinel 以了解当前的主连接信息。每当客户端失去连接时,他们都会重复此过程。Sentinel 不是 Redis 的代理 - Redis 的命令直接转到 Redis。
运行少于三个哨兵的哨兵的唯一可靠原因是服务发现,这意味着不将其用于故障转移管理。
考虑两个主机场景:
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 的客户端都将被告知主机 B 是主机,而连接到 Sentinel 1 的客户端将被告知主机 A 主机(如果您的 Sentinel 位于负载均衡器后面,则意味着一半的客户端)。
因此,您需要运行以获得最低可接受的可靠故障转移管理是:
Host A: Redis master
Host B: Redis Slave
Host C: Sentinel 1
Host D: Sentinel 2
Host E: Sentinel 2
您的客户端连接到哨兵并获取 Redis 实例的当前主服务器(按名称),然后连接到它。如果主服务器死亡,客户端应该断开连接,因此客户端将/应该再次连接到 Sentinel 并获取新信息。
每个客户端库处理此问题的能力取决于该库。
理想情况下,主机 C、D 和 E 位于您连接到 Redis 的同一主机上(即客户端主机)。或代表一个好的抽样得到了他们。这里的主要目的是确保您从需要连接到 Redis 的位置进行检查。未能将它们放置在与客户端相同的 DC/机架/区域中。
如果您想让您的客户端与负载均衡器通信,请尽可能尝试在这些 LB 节点上设置您的 Sentinel,根据需要添加额外的非 LB 主机以获得奇数个 > 2 的 Sentinel。如果您的客户端主机是动态的,因为它们的数量是不一致的(例如,它们为流量增加,在缓慢的时期减少)。在这种情况下,您几乎必须在非客户端和非 redis 服务器主机上运行 Sentinel。
请注意,如果您这样做,您将需要编写一个守护程序来监视 Sentinel PUBSUB 通道,以便更新主开关事件以更新 LB - 您必须将其配置为仅与当前主设备对话(切勿尝试与两者对话)。这样做需要做更多的工作,但确实使用对客户端透明的 Sentinel——它只知道与 LB IP/端口通信。