我正在尝试使用hazelcast为我的项目设置分布式执行程序服务。将运行的某些任务只能在具有OS特定实用程序的计算机上完成。有没有办法提交将在群集的子集上运行一次的任务?或者注册它应该与特定执行程序服务一起使用?
查看API有许多提交任务的选项,但提交给多个成员的所有选项都将在所有这些成员上运行任务,而不是其中一个成员。
我查看了javadoc并发现有很多方法可以将Runnable对象提交给执行程序服务:
void executeOnMember(Runnable command, Member member)
- 这只允许我指定一个成员,我需要指定一组成员。
void executeOnMembers(Runnable command, Collection<Member> members)
- 这允许我指定成员集合,但多次运行任务而不是一次。
void submitToMembers(Runnable task, Collection<Member> members, MultiExecutionCallback callback)
- 再次指定成员集合,但它会多次运行任务。
答案 0 :(得分:1)
我打算将评论复制为答案,因为这个问题因我之外的原因而关闭了一段时间。
我会使用IExecutorService.executeOnMember。如果要在成员子集的其中一个成员上执行,请随机选择一个成员或使用某种负载均衡策略(例如循环法或检测实际负载),然后执行executeOnMember。
你也可以通过Executor装饰器包装IExecutorService来处理这个问题:
class OsSpecificExecutor implements Executor{
private IExecutorService ex;
public void execute(Runnable task){
Set<Member> targetMembers = getYourTargetMembers()
Member member = random(targetMembers)
ex.executeOnMember(task, member);
}
}
通过这种方式,您可以将其用作普通执行程序,但在下面您可以控制哪些成员+可选的负载平衡。
答案 1 :(得分:0)
我会采用与pveentjer不同的方法,因为随机算法可能随机选择频繁使用的节点,执行将被延迟。我会提交作业在所有(或一组)成员上运行。要仅在一台计算机上实际运行作业,您可以使用最初初始化为0的原子整数。每个作业将原子地增加此原子整数,但只有作为incrementAndGet()的结果接收1的作业才会实际运行,其他将返回立即伪造价值。 然而,群集范围的incrementAndGet()不是即时的,会给作业本身增加轻微的开销。