我观察到在收集提交给 IExecutorService 的任务的结果时存在一些延迟。这仅在尝试通过使用继承自 ExecutorService 的提交(可调用任务)以 future 形式收集结果的情况下。我还发现,当您通过异步回调收集结果时,性能很好。 考虑到 future 也是异步的,我试图理解为什么在检索结果方面存在滞后。它是否特定于 hazelcast 的工作方式?
此外,如果我正在使用 submit(Callable task, ExecutionCallback callback) ,我应该期待什么样的行为?我是否应该期望它随机选择一个成员在有或没有负载平衡的情况下执行?
编辑:用一些示例代码更新问题。我将 future 存储在集合中并稍后检索它。但是当主线程继续读取 future 值时,与异步回调相比,我看到了延迟。
final IExecutorService executorService = hz.getExecutorService("default");
List<Future<String>> list = Lists.newArrayList();
for (int i = 0; i < 100; i++) {
final Future<String> f = executorService.submit(new Echo(" " + i));
list.add(f);
}
System.out.println();
for (Future<String> f : list){
System.out.println(f.get());
}
相对于
final IExecutorService executorService = hz.getExecutorService("default");
final List<String> list = Lists.newArrayList();
final Stopwatch stopwatch = Stopwatch.createStarted();
for (int i = 0; i < 100; i++) {
executorService.submit(new Echo(" " + i), new ExecutionCallback<String>() {
@Override
public void onResponse(String response) {
System.out.println(response);
list.add(response);
if(list.size() == 100){
stopwatch.stop(); // optional
long millis = stopwatch.elapsed(TimeUnit.MILLISECONDS);
System.out.println("time taken to complete is: "+millis);
}
}
@Override
public void onFailure(Throwable t) {
t.printStackTrace();
}
});
最佳答案
很难回答:)
当您在提交后立即执行 future.get 时,您不会给线程运行的机会,但它们会在大部分时间阻塞。当你第一次提交一大堆并将 future 存储在一个集合中时,我猜你会获得与异步执行相似的性能。这样提交操作不会在完成时阻塞,而且工作线程也不会阻塞队列,因为队列中充满了操作。因此,您可以获得更好的吞吐量。
我正在基于 Java 8 的 CompleteableFuture 为 Hazelcast 开发一个响应式(Reactive) API,因此您可以直接在未来注册您的回调。最终,带有回调的提交将被删除。
而且我还在研究新的 OperationService 实现;负责实际执行操作的 Hazelcast 的“引擎”。我正在尝试各种优化,比如调用者运行优化,它可以防止操作排队的所有常规开销。这也与 future 紧密结合,我想从性能中榨取更多;特别是本地电话。
[编辑] 它只会随机选择集群中的一个成员。如果你想要负载均衡,你需要弄清楚哪个成员是任务的最佳目标,然后使用
void submitToMember(Runnable task, Member member, ExecutionCallback callback);
关于java - 是否建议将 ExecutionCallBacks 用于分布式执行程序服务 - hazelcast,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20685773/