【问题标题】:Hazelcast/Coherence Grid Computing EntryProcessor with data for each keyHazelcast/Coherence Grid Computing EntryProcessor,每个键都有数据
【发布时间】:2016-10-18 07:12:30
【问题描述】:

我想使用 hazelcast 或 coherence EntryProcessor 在密钥存储在缓存中的不同节点上处理一些并行执行的逻辑。我知道我可以使用 sendToEachKey(EntryProcessor process) 之类的东西。

当我还需要使用逻辑发送一条属于另一个系统的要处理的数据并且我接收到它(例如在 http 请求中)时,我的问题就出现了。

当然我可以做类似 sendToEachKey(EntryProcessor(data) process) 的事情。但是,如果每个键的数据不同,并且我只想将他的数据发送到特定键,我该怎么做?我之所以要这样做是因为数据太大而且我的网络过载。

当然,如果我打开一个线程池将每个数据发送到每个键是可能的,但由于请求量很大,它效率低下。

谢谢!

【问题讨论】:

    标签: hazelcast oracle-coherence grid-computing


    【解决方案1】:

    对于 Hazelcast,您可以检索所有值并发送它自己的每个键 EntryProcessor,但这会产生很多开销。

    另一种选择是使用EntryProcessor 和我们分发的ExecutorService 的组合。

    您将Runnable 发送到 ExecutorService。在Runnable 中,您检索本地键集,检索所有外部值(所有已经在节点本地的值),然后为每个本地键发出一个EntryProcessor。由于您已经在该节点本地,因此没有更多的流量飞来飞去(除了备份,显然:))。也就是说,您可能希望实现一个特定的EntryProcessor,它只传输更改的值而不传输整个处理器本身(以节省更多流量)。

    【讨论】:

    • 这个。我是来写同样的推荐的。IExecutorService.submitToKeyOwner(Callable/Runnable, key)可以用来轻松解决。
    • 谢谢!这是我认为最好的。
    【解决方案2】:

    在 Coherence 中,您可以使用 PartitionedService 来查找缓存键与集群成员的关联。然后,您可以使用每个成员的数据调用入口处理器,使用PartitionedFilter 确保数据仅发送给该成员。像这样的:

    // keys in this map are also keys in cache
    void processData(Map<String, Data> externalData) { 
        PartitionedService partitionedService = (PartitionedService) cache.getCacheService();
        Map<Member, Map<String, Data>> dataForMembers = splitDataByMembers(partitionedService, externalData);
    
        for (Entry<Member, Map<String, Data>> dataForMember : dataForMembers.entrySet()) {
            Member member = dataForMember.getKey();
            Map<String, Data> data = dataForMember.getValue();
    
            PartitionSet partitions = partitionedService.getOwnedPartitions(member);
            PartitionedFilter filter = new PartitionedFilter<>(Filters.always(), partitions);
            EntryProcessor processor = new MyEntryProcessor(data);
            cache.async().invokeAll(filter, processor);
        }
    }
    
    Map<Member, Map<String, Data>> splitDataByMembers(
            PartitionedService partitionedService,
            Map<String, Data> externalData) {
        Map<Member, Map<String, Data>> dataForMembers = new HashMap<>();
    
        for (Object member : partitionedService.getInfo().getServiceMembers()) {
            dataForMembers.put((Member) member, new HashMap<>());
        }
        for (Entry<String, Data> dataForKey : externalData.entrySet()) {
            Member member = partitionedService.getKeyOwner(dataForKey.getKey());
            dataForMembers.get(member).put(dataForKey.getKey(), dataForKey.getValue());
        }
        return dataForMembers;
    }
    

    这样,集群中的每个成员只有一个入口处理器调用,每个成员将只获得它感兴趣的数据。

    我使用String 作为缓存键和任意Data 类型用于与此键关联的数据,但您当然可以使用任何其他类型(并且您根本不必将外部数据建模为映射)。

    【讨论】:

      【解决方案3】:

      在 Hazelcast 中,您将使用 executeOnKeys(keys, new EntryProcessor(data)),这太多了,因为数据太大了。

      为什么不

      executeOnKey(key1, new EntryProcessor(data1));
      executeOnKey(key2, new EntryProcessor(data2));
      executeOnKey(key3, new EntryProcessor(data3));
      

      发送每个键需要的数据子集?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-09-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-07-28
        相关资源
        最近更新 更多