在具有哨兵的AWS上设置Redis HA - 不同哨兵看到的redis节点最终在无限循环中

时间:2016-10-13 03:45:10

标签: amazon-web-services redis devops autoscaling redis-sentinel

我们的设置

  • 每个AWS Sydney AZ上有3个redis哨兵一个
  • 2到500个带有主设备和多个从设备的redis节点 使用AWS自动扩展组策略自动水平扩展
  • 1x写入将流量推送到主人的ELB
  • 1x读取将流量推送到奴隶的ELB
  • 1x Sentinel ELB将流量推送到哨兵
  • 1x辅导员(更多关于此波纹管)

此设置在两个群集中复制,用于我们称之为元数据缓存的内容。我们希望部署更多集群。

主持人

是我们构建的python守护程序,它订阅了sentinels pub / sub并侦听 + switch-master 消息。以下是协调人采取的行动:

  1. 检测并控制+ switch-master
  2. 触发的故障转移
  3. 使用SENTINEL get-master-addr-by-name mymaster
  4. 查询新主控的标记
  5. 使用RedisClusterNodeRole = slave
  6. 标记旧主控
  7. 使用RedisClusterNodeRole = master
  8. 标记新主控
  9. 将新的主人添加到我们的写作ELB中
  10. 从阅读ELB中删除新主人
  11. 从写ELB中删除旧主人
  12. 尝试将旧主服务器添加到我们的读取ELB中(如果服务器已关闭,这将失败,这很好)
  13. 问题

    因为奴隶每天可以来回走动多次,取决于交通,我们最终会遇到属于同一个奴隶争夺同一奴隶的哨兵的一些奴隶。发生这种情况是因为IP池在集群之间共享,并且据我们所知,从属ID是它们的IP。

    以下是如何复制:

    1. 群集缓存具有IP 172.24.249.152
    2. 的主服务器
    3. 群集缓存具有主故障转移提升从属,IP 172.24.246.142 到主服务器。 IP 172.24.249.152的节点现已关闭
    4. 群集元数据向上扩展,DHCP分配IP 172.24.249.152 (群集缓存上的上一个主数据库)
    5. 群集缓存将看到它之前的主服务器已启动并将尝试将其重新配置为 172.24.246.142 (缓存群集上的新主服务器)的从属服务器
    6. 群集元数据将触发 172.24.246.142 上的+ sdown,并在一段时间后-sdown后跟+ slave-reconf-sent向它尝试将其重新配置为元数据群集的从属
    7. 群集缓存将尝试执行与群集元数据在第5点上执行的操作相同的操作。
    8. 哨兵陷入无休止的循环中,永远为这种资源而战。即使我们只有一个哨兵小组管理具有不同主名称的两个redis群集,这种情况也会发生。这使我们相信哨兵不了解不同集群之间的资源,而是分别为每个集群做了合乎逻辑的事情。

      我们尝试的解决方案

      1. 在+ sdown事件后触发SENTINEL reset mymaster,尝试让哨兵忘记该节点。问题是,如果该集群正在执行主故障转移,它可能会生成竞争条件。我们成功地复制了这个假设,并且让哨兵不同步,其中一个指向一个主人,另外两个指向另一个主人。
      2. 将网络分为每个群集一个IP池。这是有效的,因为IP不会被重用,但是当我们需要一个新的集群时,它也会使事情变得更加灵活和复杂。这是我们最终要解决的问题,但我们希望尽可能避免使用它。
      3. 理想解决方案

        1. Redis哨兵提供SENTINEL removeslave 172.24.246.142 mymaster我们可以在每次有奴隶的+ sdown事件时运行。这将使该群集忘记该奴隶曾经存在而不会产生SENTINEL reset mymaster所具有的副作用。

        2. 仅通过IP停止识别奴隶的唯一性。也许添加一个redis服务器启动时间戳或任何其他令牌,以防止关闭的从站和使用相同IP备份的新站点被视为同一节点。

        3. 问题

          你能想到任何其他解决方案并不涉及改变redis哨兵代码而且不需要在集群之间隔离IP池吗?

0 个答案:

没有答案