2016-10-18 57 views
0

我希望使用hazelcast或Coherence EntryProcessor在密鑰存儲在緩存中的不同節點上並行執行某些邏輯。我看到我可以使用像sendToEachKey(EntryProcessor進程)的東西。Hazelcast/Coherence Grid Computing EntryProcessor爲每個密鑰提供數據

我的問題來了,當我需要發送邏輯一塊數據也處理屬於另一個系統,我收到它(例如在一個HTTP請求)。

當然,我可以做一些像sendToEachKey(EntryProcessor(數據)過程)。但是,如果數據與每個密鑰不同,並且我想發送給特定密鑰只有他的數據要處理,那我該怎麼做?爲什麼我想這樣做是因爲數據太大,我有網絡過載。

當然,如果我打開一個線程池發送每個數據到每個鍵是可能的,但由於巨大的請求,它是低效的。

謝謝!

回答

1

對於Hazelcast,您可以檢索所有值併發送它自己的每個密鑰EntryProcessor,但是這會造成很大的開銷。

另一種選擇是使用EntryProcessor和我們的分銷ExecutorService的組合。

您發送Runnable到ExecutorService。在Runnable內部,您可以檢索本地密鑰集,檢索所有外部值(所有本地已存在的節點)並且每個本地密鑰發出一個EntryProcessor。由於您已經是本地節點,所以沒有更多的流量四處飛散(除了備份,顯然:))。也就是說,您可能想要實現僅傳輸更改值但不包含完整處理器本身的特定EntryProcessor(以節省更多流量)。

+1

這。我來這裏寫同樣的建議.'IExecutorService.submitToKeyOwner(Callable/Runnable,key)'可以用於簡單的解決方案。 –

+0

謝謝!這是我認爲可能是最好的。 – Patrick

+0

您能否提供一些示例代碼? –

0

在Hazelcast中,你會做executeOnKeys(keys, new EntryProcessor(data)),這太多了,因爲數據太大。

爲什麼不

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

發送數據子集,每個鍵的需求?

1

在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鍵入與此鍵關聯的數據,但您當然可以使用任何其他類型(並且您不必將外部數據建模爲映射)。

相關問題