1

我有一个在集群/网格上运行的应用程序,我需要在其中运行 N 个不必通信的任务。我只需要收集每个任务的结果。所以我有一个主人将任务分配给一些奴隶(可能在不同的主机上运行)并在最后结合所有结果。

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

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

MPJ - 对我不起作用,因为当同一台机器上有多个处理器可用时,MPJ 的运行方式。它使用自定义类加载器,这给我正在加载的本机库带来了问题(它被加载多次,因为自定义类加载器多次加载该类)。

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

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

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

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

Akka - 似乎也有点矫枉过正。并且有很多配置来设置节点组。

Hadoop - 像 Akka 似乎有点过头了,尤其是设置节点组的配置。

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

所以我会坚持使用 Hazelcast 或 Simon。哪一个更适合这种应用?有谁知道另一个库(不太重,没有太多配置)。还有其他建议吗?

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

4

2 回答 2

0

我终于和 MPJ 安定下来了。通过不使用 MPJ 中包含的脚本,而是使用以下参数直接调用 java 程序,可以简单地规避自定义类加载器的问题:

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

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

3
131072
a6444@20000@0
a6444@20002@1
a6413@20000@2

将同一主机上的端口号分开 2 很重要,因为 MPJ 使用指定的端口 + 下一个端口(例如 20000 和 20001)。

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

于 2013-08-12T14:36:14.530 回答
0

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

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

接着

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();

您唯一需要做的就是MyCallableTask在所有节点的类路径中拥有类。

于 2013-08-13T17:57:47.867 回答