正在听重新分区事件吗?

时间:2019-01-11 07:48:18

标签: hazelcast hazelcast-imap

我正在尝试使用Hazelcast的分布式地图,以基本上将元素分布在同一应用程序的多个实例中。想法是首先启动一个应用程序,然后填充地图。当然,本地密钥集将是完整的地图。

当另一个实例加入群集时,将对映射进行重新分区,以使两个实例都将映射条目的一半(我认为是)作为其本地键集。

Config hzConfig = new Config("hz");
HazelcastInstance hzInstance = HazelcastInstanceFactory.newHazelcastInstance(hzConfig);
IMap<Long, Long> test = hzInstance.getMap("test");
LocalListener listener = new LocalListener();
test.addLocalEntryListener(listener);
test.addPartitionLostListener(listener);

我以为重新分区会调用本地条目侦听器,但显然不会,实际上它不会调用任何其他侦听器。

具体的用例是,第一个应用程序填充了地图,当其他应用程序加入时,条目散布在它们上,并且对于其本地密钥集中的每个条目,他们都必须执行某些操作。与其定期检查本地密钥集,不如对诸如从本地密钥集添加/删除事件进行检查。

但是,如果一个实例加入或离开集群,则会发生重新分区(我希望总是如此),但是我似乎听不清是哪种目的失败了。

使用上面的配置和下面的侦听器,我有一个测试应用程序,该应用程序每10秒将随机长整数放入地图中。

private static class LocalListener implements EntryAddedListener<Long, Long>, EntryRemovedListener<Long, Long>,
        EntryUpdatedListener<Long, Long>, EntryEvictedListener<Long, Long>, MapClearedListener, MapPartitionLostListener {
    @Override
    public void entryAdded(EntryEvent<Long, Long> event) {
        LOG.info("An entry was added to the local set: {}", event.getValue());
    }
    @Override
    public void entryRemoved(EntryEvent<Long, Long> event) {
        LOG.info("An entry was removed from the local set: {}", event.getValue());
    }
    @Override
    public void entryEvicted(EntryEvent<Long, Long> event) {
        LOG.info("An entry was evicted from the local set: {}", event.getValue());
    }
    @Override
    public void entryUpdated(EntryEvent<Long, Long> event) {
        LOG.info("An entry was updated in the local set: {}", event.getValue());
    }
    @Override
    public void mapCleared(MapEvent event) {
        LOG.info("The map was cleared: {}", event);
    }
    @Override
    public void partitionLost(MapPartitionLostEvent event) {
        LOG.info("A partition was lost: {}", event);
    }
}

第一个测试实例的输出:

15:43:47.718 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry -1012665372499231549
15:43:47.858 [hz.hz.event-4] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: -1012665372499231549
15:43:57.716 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry -5501878816285329759
15:43:57.717 [hz.hz.event-1] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: -5501878816285329759

然后我启动第二个实例,它加入集群。

实例1的输出:

INFO: [172.20.20.7]:5701 [dev] [3.9.3] Re-partitioning cluster data... Migration queue size: 271
15:44:12.137 [hz.hz.event-4] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: -642323604672752630
jan 10, 2019 3:44:12 PM com.hazelcast.internal.partition.impl.MigrationThread
INFO: [172.20.20.7]:5701 [dev] [3.9.3] All migration tasks have been completed, queues are empty.
15:44:17.716 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry -2929992218325845758
15:44:17.718 [hz.hz.event-2] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: -2929992218325845758
15:44:27.716 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry -7717112084150209257
15:44:27.717 [hz.hz.event-3] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: -7717112084150209257
15:44:37.716 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry -3756253634059275245
15:44:37.717 [hz.hz.event-3] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: -3756253634059275245
15:44:47.716 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry 9175632974694161488

实例2的输出:

15:44:12.131 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry -642323604672752630
15:44:22.130 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry -785281121378041075
15:44:22.136 [hz.hz.event-1] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: -785281121378041075
15:44:32.130 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry 3465608643988715362
15:44:32.132 [hz.hz.event-1] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: 3465608643988715362
15:44:42.131 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry 1474484225334222922
15:44:42.133 [hz.hz.event-1] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: 1474484225334222922
15:44:47.719 [hz.hz.event-1] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: 9175632974694161488
15:44:52.130 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry -4535267276695561636
15:44:52.131 [hz.hz.event-2] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: -4535267276695561636

然后我关闭第二个实例以触发重新分区。

实例1的输出:

INFO: [172.20.20.7]:5701 [dev] [3.9.3] Partition balance is ok, no need to re-partition cluster data... 
jan 10, 2019 3:45:03 PM com.hazelcast.spi.impl.operationservice.impl.InvocationMonitor
INFO: [172.20.20.7]:5701 [dev] [3.9.3] Invocations:1 timeouts:0 backup-timeouts:1
15:45:07.716 [pool-1-thread-1] INFO com.example.playground.DistributedMapTests - Adding new entry -4645280647407966219
15:45:07.716 [hz.hz.event-5] INFO com.example.playground.DistributedMapTests - An entry was added to the local set: -4645280647407966219

按预期,当单独使用应用程序时,它具有所有条目,并且当另一个实例加入时,发生了重新分区,但是,第二个实例并不知道它现在在本地密钥集中具有更多元素,直到发生另一个放置

另外,当第二个实例离开时,由于某种原因没有重新分区,所以我不知道它在其本地键集中的条目发生了什么。

所以TL; DR:我想知道如何监听重新分区事件。也许在Hazelcast中有这种选择吗?

更新

通过进一步的测试,尽管说分区平衡还可以,但是离开集群的那个条目的确返回了其他实例。我假设该消息意味着不需要将其重新分配给不同的成员,因为仅剩一个。

2 个答案:

答案 0 :(得分:0)

听重分区事件是错误的想法。当成员身份发生更改时,将发生重新分区。侦听成员资格变更以及条目变更将涵盖所有需要的事件。

答案 1 :(得分:0)

本地条目侦听器仅由用户操作触发。只要将成员添加到集群或从集群中删除成员,就会发生重新分区。而且,如果您的集群大小仍然> 1,则将进行迁移,您可以使用进行监听 migration listeners

OTOH,如果某个成员不愉快地离开了集群,那么其余成员将从他们自己的备份中恢复其数据。这可能就是您所看到的。

但是我不明白为什么您需要聆听迁移事件并对其采取行动。它与您的业务逻辑有关吗?否则,您不必担心密钥的位置,只需通过使用密钥将任何业务逻辑发送到集群即可。请详细说明我是否有任何遗漏。