【问题标题】:Finding out when MapLoader finished (eager) loading in Hazelcast在 Hazelcast 中找出 MapLoader 何时完成(急切)加载
【发布时间】:2019-05-28 22:02:13
【问题描述】:

我使用 MapLoader 将数据从数据存储区初始加载到 Hazelcast (InitialLoadMode = EAGER)。我需要从在此加载过程开始时为加载而创建的物化视图中加载此数据,并且在加载完成后,我需要删除此物化视图。

有什么方法可以告诉 Hazelcast 在我开始使用 MapLoader 加载数据之前触发我的代码创建此视图?

在初始加载完成后,Hazelcast 有什么方法可以通知?我查看了听众,但我只看到了那些关于单一价值的人。

我想出的唯一方法是在 MapLoader.loadAllKeys() 中创建物化视图(它保证它只会执行一次,并且它会在任何人可以从地图中获取某些东西之前执行,因此在任何人之前可以无意中调用加载过程),然后在其他地方调用 getMap("") (我使用 EAGER),当它完成时,删除实体。

有更好的方法吗?

【问题讨论】:

  • 据我了解,您需要使用 MapLoader 加载(一次?在应用程序启动时?)一些键集合。并且您需要尝试从地图中读取的其他线程在加载完成时等待。对吗?
  • 我需要创建用于执行初始加载的数据库实体(与 MapLoader 一样),然后在加载完成后删除这些数据库实体。所以我需要在加载开始之前运行一段代码,然后在加载完成后运行另一段代码。
  • 数据库中的实体是在应用程序启动时添加的还是由其他事件添加的?
  • 这是正常 Hazelcast 初始加载过程的一部分,我需要创建与此过程相关的实体。地图由 Hazelcast 使用 MapLoaders 加载,它们有自己的生命周期。我需要在加载开始之前创建这些实体(并且它可以随时由任何缓存客户端触发)并在它结束后删除它们。此外,我只需要为整个集群执行一次,而不是为每个集群成员执行一次。

标签: java hazelcast


【解决方案1】:

如果您需要完全控制初始化过程,那么您可能需要在不使用 MapLoader 的情况下手动填充地图:

public class MapWrapper {

    private Lock lock = hazelcastInstance.getLock("map-lock");
    private IAtomicLong mapIsLoaded = ...;
    ICountDownLatch latch = hazelcastInstance.getCountDownLatch("map-loaded");

    public MapWrapper() {
        latch.trySetCount(1);
    }

    public void initialize() {
        lock.lock();
        // Loading:
        try {
            // Skip loading if map already loaded (ensure only once for cluster)
            if(mapIsLoaded.get() == 1) {
                return;
            }
            mapIsLoaded.set(0);
            // Here code to load your map, clean database:
            initializeDatabase();
            loadMap();
            cleanDatabase();
        } finally {
            latch.countdown();
            mapIsLoaded.set(1);
            lock.unlock();
        }
    }

    public Map getMap() {
        // Blocking until loading is completed:
        latch.await();
        return hazelcastInstance.getMap(...);
    }
}

【讨论】:

  • 这是一个有趣的解决方案,但存在一些问题: 1. 嵌入式集群 - 这将起作用 2. 客户端 - 服务器 - 如果在集群(服务器)端运行,这将不起作用,因为那里必须在客户端进行额外的同步(这使得这个解决方案有点麻烦)。如果它放在客户端上,每个使用它的客户端也必须使用这个同步代码,这又使它变得很麻烦。但总的来说,这是一个有趣的选择。我可以使用其中的一部分来增强我最初的想法。
  • @rattaman 你能否澄清一下关于客户端额外同步的问题?为什么需要它?
  • 因为如果客户端在服务器完成加载地图之前调用getMap,他会得到部分结果。
  • @rattaman 这应该由latch.await()处理;在 getMap() 中,或者我错过了什么?
  • 您提供的整个同步位正在服务器上完成。所以地图只在服务器端被锁定。如果你想在客户端使用它而不会有部分加载的风险,你必须在同一个闩锁上等待。所以这个代码latch.await也必须出现在客户端。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-09
  • 2013-02-28
  • 2022-01-09
  • 2012-09-16
  • 1970-01-01
  • 1970-01-01
  • 2017-10-19
相关资源
最近更新 更多