【问题标题】:Timeout configurations in CuratorCurator 中的超时配置
【发布时间】:2015-01-12 23:00:32
【问题描述】:

我创建一个 Curator 客户端如下:

    RetryPolicy retryPolicy = new RetryNTimes(3, 1000);
    CuratorFramework client = CuratorFrameworkFactory.newClient(zkConnectString, 
            15000, // sessionTimeoutMs
            15000, // connectionTimeoutMs
            retryPolicy);

在运行我的客户端程序时,我通过关闭 Curator 用来与 Zookeeper 通信的 NIC 来模拟网络分区。根据我看到的行为,我有几个问题:

  1. 我在 10 秒后看到 ConnectionStateManager - State change: SUSPENDED 消息。直到 Curator 进入 SUSPENDED 状态的时间量是可配置的,基于其他超时值的百分比,还是始终为 10 秒?
  2. 自上次成功的检测信号后配置的 15 秒会话超时后,我没有收到 任何 通知。我确实在日志中看到了一条ZooKeeper - Session: 0x14adf3f01ef0001 closed 消息,但是这似乎并没有作为我可以捕获或监听的事件来传播。我在这里遗漏了什么吗?
  3. 我最终在连接丢失大约两分钟后收到ConnectionStateManager - State change: LOST 消息。为什么这么久?
  4. 如果我的目标是在 HA 场景中使用 InterProcessMutex 作为防止脑裂的一种方法,似乎最安全的方法是让锁持有者在SUSPENDED 消息出现时假设它已丢失锁收到,因为 Zookeeper 完全有可能释放了锁 它在网络分区的另一端不知道。这是一种典型/理智的方法吗?

【问题讨论】:

  • 您找到问题的答案了吗?我也遇到了同样的问题。

标签: apache-zookeeper apache-curator


【解决方案1】:

这取决于你使用的是哪个版本的 Curator(注意:我是 Curator 的主要作者)...

在 Curator 2.x 中,LOST 状态意味着重试策略已用尽。这并不意味着会话已经丢失。在 ZooKeeper 中,只有在修复与 ensemble 的连接后才会确定会话丢失。因此,当 Curator 看到第一条“断开连接”消息时,您会被暂停。然后,当由于重试策略放弃而导致操作失败时,您会丢失。

在 Curator 3.x 中更改了 LOST 的含义。在 3.x 中,当收到“断开连接”时,Curator 会启动一个内部计时器。当计时器超过协商的会话超时时间时,Curator 调用 getTestable().injectSessionExpiration() 并发布 LOST 状态更改。

【讨论】:

    【解决方案2】:

    正确。假设在 SUSPEND 和 LOST 中失去了领导权。 这就是 Apache Curator 配方的工作方式。 您可能想要使用 Apache Curator 而不是实现自己的算法。 https://curator.apache.org/curator-recipes/index.html

    【讨论】:

      【解决方案3】:

      第一个问题,Zookeeper 有一个名为 MAX_SEND_PING_INTERVAL 的变量,它是 10 秒,所以根据您的情况,它总是 10 秒。代码在 ClientCnxn 类中。

      //1000(1 second) is to prevent race condition missing to send the second ping
      //also make sure not to send too many pings when readTimeout is small 
      int timeToNextPing = readTimeout / 2 - clientCnxnSocket.getIdleSend() - 
              ((clientCnxnSocket.getIdleSend() > 1000) ? 1000 : 0);
      //send a ping request either time is due or no packet sent out within MAX_SEND_PING_INTERVAL
      if (timeToNextPing <= 0 || clientCnxnSocket.getIdleSend() > MAX_SEND_PING_INTERVAL) {
          sendPing();
          clientCnxnSocket.updateLastSend();
      } else {
          if (timeToNextPing < to) {
              to = timeToNextPing;
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-23
        • 2020-05-02
        • 2013-02-06
        • 1970-01-01
        • 2013-08-28
        • 1970-01-01
        • 1970-01-01
        • 2014-05-14
        相关资源
        最近更新 更多