使用C#中的StackExchange/Sentinel进行Redis故障转移

Pau*_*ulB 12 c# failover redis sentinel stackexchange.redis

我们目前正在使用Redis 2.8.4和StackExchange.Redis(并且喜欢它),但目前还没有针对硬件故障等的任何形式的保护.我正在尝试使解决方案正常工作,我们有主/从和监控但不能完全到达那里,我在搜索后找不到任何真正的指针.

所以目前我们已经做到了这一点:

我们在每个节点上有3个redis服务器和sentinel(由Linux人员设置):devredis01:6383(master)devredis02:6383(slave)devredis03:6383(slave)devredis01:26379(sentinel)devredis02:26379(sentinel)devredis03: 26379(哨兵)

我能够将StackExchange客户端连接到redis服务器并进行写入/读取,并使用Redis Desktop Manager验证是否正在跨所有redis实例复制数据.

我也可以使用不同的ConnectionMultiplexer连接到sentinel服务,查询配置,请求主redis节点,请求奴隶等.

我们还可以终止主redis节点并验证其中一个从服务器是否已升级为主服务器,并且复制到另一个从服务器继续工作.我们可以观察redis连接尝试重新连接到主设备,如果我重新创建ConnectionMultiplexer,我可以再次写入/读取新升级的主设备并从从设备读取.

到现在为止还挺好!

我缺少的是你如何在生产系统中将它们整合在一起?

我应该从sentinel获取redis端点并使用2个ConnectionMultiplexers吗?我究竟需要做些什么来检测节点是否已经关闭?StackExchange可以自动为我执行此操作还是通过事件,以便重新连接我的redis ConnectionMultiplexer?我应该处理ConnectionFailed事件然后重新连接,以便ConnectionMuliplexer找出新主设备是什么?据推测,当我重新连接任何写入的尝试都会丢失?

我希望我不会错过一些非常明显的东西,我只是在努力将它们放在一起.

提前致谢!

Pau*_*ulB 7

我上周花了一些时间与Linux人员测试场景并在这个实现的C#方面工作,并使用以下方法:

  • 从config读取sentinel地址并创建ConnectionMultiplexer以连接它们
  • 订阅+ switch-master频道
  • 每个哨兵服务器依次询问他们认为的主人redis和奴隶是什么,比较他们所有人以确保他们都同意
  • 使用从sentinel和connect读取的redis服务器地址创建一个新的ConnectionMultiplexer,将事件处理程序添加到ConnectionFailed和ConnectionRestored.
  • 当我收到+ switch-master消息时,我在redis ConnectionMultiplexer上调用Configure()
  • 作为带和括号方法,当连接类型为ConnectionType.Interactive时,我总是在接收到connectionFailed或connectionRestored事件12秒后在redis ConnectionMultiplexer上调用Configure().

我发现通常我工作并在失去redis主机约5秒后重新配置.在这段时间我不能写,但我可以读(因为你可以读取一个奴隶).5秒对我们来说是好的,因为我们的数据非常快速地更新并且在几秒钟后变得陈旧(并且随后被覆盖).

我不确定的一件事是我是否应该在实例关闭时从redis ConnectionMultiplexer中删除redis服务器,或者让它继续重试连接.我决定让它重试,因为它一旦恢复就会重新成为奴隶.我做了一些性能测试,有没有连接被重试,它似乎没什么区别.也许有人可以澄清这是否是正确的方法.

每次不时地带回一个以前是高手的实例似乎都会引起一些混乱 - 在它恢复后几秒钟我会收到写入的异常 - "READONLY"表示我无法写入奴隶.这种情况很少见,但我发现在连接状态更改后12秒调用Configure()的"全能"方法会遇到此问题.调用Configure()似乎非常便宜,因此无论是否必要,都调用它两次似乎没问题.

现在我有了奴隶,我已经卸载了一些我的数据清理代码,这些代码对从属进行了密钥扫描,这让我感到高兴.

总而言之,我非常满意,它并不完美,但对于一些很少发生的东西,它已经足够好了.


Ben*_*rey 2

我刚刚问了这个问题,发现了一个与你和我的类似的问题,我相信它回答了这样的问题:当当前主服务器宕机时,我们的代码(客户端)现在如何知道哪个是新的主服务器?

如何使用 Sentinel 告诉客户端新的 Redis 主节点在哪里

显然,您只需要订阅并收听来自哨兵的事件即可。有道理..我只是想有一种更精简的方法。

我读过一些有关 Linux 版 Twemproxy 的内容,它充当代理,可能会为您做这件事?但我使用的是 Windows 版的 redis,并试图找到一个 Windows 选项。如果这是经过批准的方式,我们可能会转向 Linux。