如何在群集中的应用程序上运行相同的IScheduledExecutorService时防止重复任务?

时间:2018-04-04 10:20:09

标签: hazelcast hazelcast-imap

我想了解IScheduledExecutorService的hazelcast方法之间的区别,以防止重复的任务。 我有两个带有HazelcastInstance的Java应用程序。我分别有两个HazelcastInstances(服务器)的hazelcast集群。 我使用IMap并希望每隔午夜重置AtomicLong。

    config.getScheduledExecutorConfig("my scheduler")
            .setPoolSize(16)
            .setCapacity(100)
            .setDurability(1);


class DelayedResetTask implements Runnable, HazelcastInstanceAware, Serializable {

    static final long serialVersionUID = -7588380448693010399L;

    private transient HazelcastInstance client;

    @Override
    public void run() {
        final IMap<Long, AtomicLong> map = client.getMap(HazelcastConfiguration.mapName);

        final ILogger logger = client.getLoggingService().getLogger(HazelcastInstance.class);
        logger.info("Show data in cache before reset: " + map.entrySet());
        map.keySet().forEach(key -> map.put(key, new AtomicLong(0)));
        logger.info("Data was reseted: " + map.entrySet());
    }

    @Override
    public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.client = hazelcastInstance; }
}

private void resetAtMidnight() {
    final Long midnight = LocalDateTime.now().until(LocalDate.now().plusDays(1).atStartOfDay(), ChronoUnit.MINUTES);

    executor.scheduleAtFixedRate(new DelayedResetTask(), midnight, TimeUnit.DAYS.toMinutes(1), TimeUnit.MINUTES);
}

我不想并行地在每个实例上执行此任务。阅读文档documentation后,我不明白如何在一个步骤中执行两个服务器中的重置(没有重复任务,一次不在两个服务器上执行)。 我可以使用哪种方法处理我的任务scheduleOnAllMembersAtFixedRatescheduleAtFixedRatescheduleOnMembersAtFixedRate。 如何在群集中的应用程序上运行相同的IScheduledExecutorService时防止重复任务?

1 个答案:

答案 0 :(得分:1)

您需要在群集中仅运行一次代码,因为您重置的地图可以从任何成员访问。两个成员都访问同一个映射实例,只有条目保存在不同的成员中。您可以使用scheduleAtFixedRate运行一次。

此外,您无需调用IMap#keySet().forEach()来遍历地图中的所有条目。相反,您可以使用EntryProcessor,如下所示:

    public static class DelayedResetTask implements Runnable, HazelcastInstanceAware, Serializable {

    static final long serialVersionUID = -7588380448693010399L;

    private transient HazelcastInstance client;

    @Override
    public void run() {
        final IMap<Long, AtomicLong> map = client.getMap(HazelcastConfiguration.mapName);

        final ILogger logger = client.getLoggingService().getLogger(HazelcastInstance.class);
        logger.info("Show data in cache before reset: " + map.entrySet());
        map.executeOnEntries(new AbstractEntryProcessor() {
            @Override
            public Object process(Map.Entry entry) {
                entry.setValue(new AtomicLong(0));
                return null;
            }
        });
        logger.info("Data was reseted: " + map.entrySet());
    }

    @Override
    public void setHazelcastInstance(HazelcastInstance hazelcastInstance) { this.client = hazelcastInstance; }