Apache zookeeper 馆长中的超时配置

Apache zookeeper 馆长中的超时配置,apache-zookeeper,apache-curator,Apache Zookeeper,Apache Curator,我创建了一个策展人客户,如下所示: RetryPolicy retryPolicy = new RetryNTimes(3, 1000); CuratorFramework client = CuratorFrameworkFactory.newClient(zkConnectString, 15000, // sessionTimeoutMs 15000, // connectionTimeoutMs r

我创建了一个策展人客户,如下所示:

    RetryPolicy retryPolicy = new RetryNTimes(3, 1000);
    CuratorFramework client = CuratorFrameworkFactory.newClient(zkConnectString, 
            15000, // sessionTimeoutMs
            15000, // connectionTimeoutMs
            retryPolicy);
在运行我的客户端程序时,我通过关闭策展人用来与Zookeeper通信的NIC来模拟网络分区。根据我所看到的行为,我有几个问题:

  • 10秒后,我看到一条
    ConnectionStateManager-状态更改:SUSPENDED
    消息。策展人进入暂停状态之前的时间是可配置的,基于其他超时值的百分比,还是始终为10秒
  • 自上次成功检测以来,配置的15秒会话超时已过,我未收到任何通知。Ido查看日志中的
    ZooKeeper-Session:0x14adf3f01ef0001 closed
    消息,但这似乎不是我可以捕获或侦听的事件。我是不是遗漏了什么
  • 在连接丢失将近两分钟后,我最终收到一条
    ConnectionStateManager-statechange:LOST
    消息。为什么这么久
  • 如果我的目标是在HA场景中使用进程间互斥作为防止大脑分裂的一种手段,那么最安全的方法似乎是让锁持有者在收到
    挂起
    消息时假设自己失去了锁,因为Zookeeper完全有可能释放了锁 它在网络分区的另一端不知道。这是一种典型的/理智的方法吗

  • 对。假设领导层在暂停和丢失时已丢失。 这就是阿帕奇策展人食谱的工作方式。 您可能希望使用Apache Curator,而不是实现自己的算法。

    这取决于您使用的是哪一版本的策展人(注意:我是策展人的主要作者)

    在Curator 2.x中,丢失状态表示重试策略已用尽。这并不意味着会话已丢失。在ZooKeeper中,只有在修复到集合的连接后,会话才会被确定为丢失。所以,当馆长看到第一条“断开连接”的信息时,你会被停职。然后,当由于重试策略放弃而导致操作失败时,您会迷路


    在《策展人3.x》中,“迷失”的含义发生了变化。在3.x中,当收到“断开连接”时,策展人启动一个内部计时器。当计时器通过协商会话超时时,管理员调用getTestable().InjectSessionExpatition()并发布丢失状态更改。

    第一个问题,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;
        }
    }
    
    //1000(1秒)是为了防止争用条件丢失而发送第二次ping
    //另外,请确保在readTimeout很小时不发送太多ping
    int timeToNextPing=readTimeout/2-clientCnxnSocket.getIdleSend()
    ((clientCnxnSocket.getIdleSend()>1000)?1000:0);
    //发送ping请求时间到期或在最大发送ping间隔内未发送数据包
    if(时间延长最大发送间隔){
    sendPing();
    clientCnxnSocket.updateLastSend();
    }否则{
    if(timeToNextPing
    您找到问题的答案了吗?我也遇到了同样的问题。