网格上的Java任务分发和收集

网格上的Java任务分发和收集,java,concurrency,grid,cluster-computing,Java,Concurrency,Grid,Cluster Computing,我有一个应用程序在集群/网格上运行,我需要运行N个不需要通信的任务。我只需要收集每个任务的结果。因此,我有一个主服务器将任务分发给一些从属服务器(可能在不同的主机上运行),并在最后合并所有结果 由于集群由批处理系统控制,因此每次运行时节点的配置都会发生变化,并且我会得到一个为我的作业分配给我的节点列表 我正在寻找一个库(纯Java)来帮助我解决这个问题。我看了以下几点: MPJ-不适合我,因为MPJ在同一台机器上有多个可用处理器时的运行方式。它使用自定义类加载器,这使我在加载本机库时遇到问题(因

我有一个应用程序在集群/网格上运行,我需要运行N个不需要通信的任务。我只需要收集每个任务的结果。因此,我有一个主服务器将任务分发给一些从属服务器(可能在不同的主机上运行),并在最后合并所有结果

由于集群由批处理系统控制,因此每次运行时节点的配置都会发生变化,并且我会得到一个为我的作业分配给我的节点列表

我正在寻找一个库(纯Java)来帮助我解决这个问题。我看了以下几点:

MPJ-不适合我,因为MPJ在同一台机器上有多个可用处理器时的运行方式。它使用自定义类加载器,这使我在加载本机库时遇到问题(因为自定义类加载器多次加载该类,所以加载了多次)

Hazelcast-原则上是可行的,但它并不是专门为此而设计的(我可以用一个队列分发作业,并将结果放回另一个队列,但这似乎有点过分)。我喜欢的是,很容易设置节点组(原则上只需要指定一个节点,其他节点可以直接连接到它)

Simon/RMI-我想我可以让每个从机向主机注册,然后让主机将作业分配给每个从机。或者让每个从机请求一个队列,作业在该队列中排队,结果应存储在该队列中

Cajo-原则上可行,但我不想在网格网络上进行多播,Cajo似乎没有办法解决这个问题

RabbitMQ-我不喜欢运行额外的服务器,它不是纯Java。与ZeroMQ相同

Akka——似乎也有点过分了。并进行了大量的节点组设置配置

Hadoop-像Akka一样似乎有些过分,尤其是设置节点组的配置

JPPF-似乎更适合设置一个长时间运行的服务器和节点集群。应用程序完成后,我需要停止所有服务器和节点。此外,它似乎依赖于任务的序列化,这对我来说不是一个选项(请参阅下文)

所以我会选择Hazelcast或Simon。哪一个更适合这种应用?是否有人知道另一个库(不太重,配置不太多)。还有其他建议吗


顺便说一句,Hazelcasts ExecutorService不是一个选项。因为我正在使用一些JNI,所以序列化将是一件痛苦的事情。

我最终与MPJ达成了和解。通过不使用MPJ中包含的脚本,而是使用以下参数直接调用java程序,可以简单地避免自定义类装入器的问题:

java类rank mpj config niodev[应用程序的附加参数]

MPI_Init调用将删除rank、mpj config和niodev参数。 mpj config是列示列组数的文件、消息协议的切换阈值以及具有相应端口号和列组的主机列表。niodev指定了通信机制(有关更多详细信息,请参阅mpjexpress文档)。配置文件可能如下所示:

3
131072
a6444@20000@0
a6444@20002@1
a6413@20000@2
将同一主机上的端口号除以2很重要,因为MPJ使用指定的端口+下一个端口(例如20000和20001)


Simon和Hazelcast也是很好的解决方案,但他们比MPJ慢了一点。尤其是两者的初始化速度都相当慢。

如果此解决方案不起作用,请告诉我。 Hazelcast通过Executor服务提供多节点任务执行

因此,您将获得希望执行任务的节点列表

然后

HazelcastInstance h = Hazelcast.newHazelcastInstance();
Set<Member> members = h.getCluster().getMembers();//or any subset given your requirement 
MultiTask<Long> multitask = new MultiTask<Long>(new MyCallableTask("default"), members);
ExecutorService es = h1.getExecutorService();
es.execute(multitask);
Collection<Long> results = multitask.get();
HazelcastInstance h=Hazelcast.newHazelcastInstance();
Set members=h.getCluster().getMembers()//或根据您的要求提供的任何子集
多任务多任务=新多任务(新MyCallableTask(“默认”),成员);
ExecutorService es=h1.getExecutorService();
执行(多任务);
收集结果=多任务.get();

您只需要在所有节点的类路径中设置
MyCallableTask

谢谢,但如上所述,“Hazelcasts ExecutorService不是一个选项。顺便说一句,因为我使用一些JNI,所以序列化将是一件痛苦的事情。”。无论如何,我认为这也比MPJ慢,因为Hazelcast将在内部使用其分布式结构来分发任务。