Hazelcast 3.3.3。群集恢复后,EntryListener中没有更新

时间:2014-11-19 16:21:33

标签: hazelcast

我在以下配置中使用Hazelcast 3.3.3(最新稳定版):2节点群集和1个客户端。 客户端将任务放入IMap,而节点执行它们并在完成后更新相应的映射值。客户通过map.addEntryListener()注册的EntryListener(entryUpdated())获得通知。

当我模拟网络问题时出现问题:" tcpkill -i lo port或port"。停止tcpkill后,群集状态会自动恢复。到现在为止还挺好。 那时有两种方式(有时是1种,有时是2种):

  1. 客户端将下一个任务放入IMap并在中间步骤失败 - hazelcast.getPartitionService()。getPartition()返回 空值。始终为null(在分钟之后),直到群集+客户端重新启动。
  2. 客户端将下一个任务放入IMap和目标节点(密钥所有者)句柄     它像以前一样(更新IMap条目)。客户没有收到通知     通过EntryListener(entryUpdated())直到集群+客户端重新启动。
  3. 我无法在日志中找到任何可疑内容(log4j.logger.com.hazelcast = debug已启用)。 尝试启用tcpkill的不同间隔:大于和小于cluster.max.no.heartbeat.seconds和cluster.max.no.master.confirmation.seconds。行为是一样的,似乎它们对问题没有影响。

    有什么想法吗?

1 个答案:

答案 0 :(得分:0)

似乎,我找到了案例2的答案。看起来是 Hazelcast bug

我查看了两个版本的源代码: 3.2.5 (我第一次遇到问题的那个)和 3.3.3 。这就是我找到的。

EventServiceImpl 类至少负责存储/提供 EventRegistration -s,订阅包含处理地图更新的订阅。当客户端告诉map.addEntryListener(..)该侦听器最终作为 EventRegistration 出现在群集 EventServiceImpl 中时。

当群集节点执行某些地图更新 EventServiceImpl 迭代其 EventRegistration -s:

@Override
public void publishEvent(String serviceName, Collection<EventRegistration> registrations,
                         Object event, int orderKey) {

    ...
    for (EventRegistration registration : registrations) {
        ...
        Registration reg = (Registration) registration;
        if (isLocal(reg)) {
            executeLocal(serviceName, event, reg, orderKey); // EXECUTION GOES HERE
            continue;
        }

        if (eventData == null) {
            eventData = nodeEngine.toData(event);
        }
        EventPacket eventPacket = new EventPacket(registration.getId(), serviceName, eventData);
        sendEventPacket(registration.getSubscriber(), eventPacket, orderKey);
    }
}

并通知感兴趣的各方。与客户端订阅相关联的注册包含对 ClientEndpoint 的引用,最终为连接以发送更新。

当群集遇到网络问题时(我使用tcpkill阻止节点之间的通信),其状态发生变化,以便客户端断开连接。 tcpkill停止后,节点成功加入群集 和客户端恢复其连接。在 EventServiceImpl 保持不知道更改的意义上,两个Hazelcast版本都无法识别此重新连接。行为因Hazelcast版本而异:

  • 3.2.5 恢复后 EventServiceImpl 不断了解陈旧 EventRegistration (与客户端的连接不再存在)。由于这个原因,未提供地图更新通知。
  • 3.3.3 陈旧 EventRegistration 已从 EventServiceImpl 中删除。但是在客户端重新连接(自动)后,他的订阅不会被恢复。