在我的应用程序中,我试图在IMap中处理数据,方案如下:
对于这种情况IMap.executeOnKeys
几乎是完美的,有一个问题 - 条目在处理时被锁定 - 实际上它会伤害吞吐量。 IMap在启动时填充,从未修改过。
是否可以在不锁定条目的情况下处理条目?如果可能,不将条目发送到另一个节点,并且不会导致网络开销(在for循环中向单个节点发送1000个任务)
以下是参考实现,以演示我想要实现的目标:
public class Main {
public static void main(String[] args) throws Exception {
HazelcastInstance instance = Hazelcast.newHazelcastInstance();
IMap<String, String> map = instance.getMap("the-map");
// populated once on startup, never modified
for (int i = 1; i <= 10; i++) {
map.put("key-" + i, "value-" + i);
}
Set<String> keys = new HashSet<>();
keys.add("key-1"); // every requst may have different key set, they may overlap
System.out.println(" ---- processing ----");
ForkJoinPool pool = new ForkJoinPool();
// to simulate parallel requests on the same entry
pool.execute(() -> map.executeOnKeys(keys, new MyEntryProcessor("first")));
pool.execute(() -> map.executeOnKeys(keys, new MyEntryProcessor("second")));
System.out.println(" ---- pool is waiting ----");
pool.shutdown();
pool.awaitTermination(5, TimeUnit.MINUTES);
System.out.println(" ------ DONE -------");
}
static class MyEntryProcessor implements EntryProcessor<String, String> {
private String name;
MyEntryProcessor(String name) {
this.name = name;
}
@Override
public Object process(Map.Entry<String, String> entry) {
System.out.println(name + " is processing " + entry);
return calculate(entry); // may take some time, doesn't modify entry
}
@Override
public EntryBackupProcessor<String, String> getBackupProcessor() {
return null;
}
}
}
提前致谢
答案 0 :(得分:0)
在executeOnKeys中,条目未锁定。也许你的意思是处理发生在partitionThreads上,因此特定键可能没有其他处理?无论如何,这是解决方案:
您的EntryProcessor应该实现: