我有一个应用在群集/网格上运行,我需要运行N个无需沟通的任务。我只需收集每项任务的结果。所以我有一个Master将任务分配给一些Slaves(可能在不同的主机上运行)并在最后结合所有结果。
由于群集由批处理系统控制,我的节点配置会针对每次运行进行更改,并且我会获得已为我的工作分配给我的节点列表。
我正在寻找一个库(纯Java)来帮助我。我看了下面的内容:
MPJ - 因为当同一台计算机上有多个处理器可用时MPJ的运行方式对我不起作用。它使用自定义类加载器,这给我带来了我正在加载的本机库的问题(它被多次加载,因为自定义类加载器多次加载类)。
Hazelcast - 原则上是有效的,但实际上并没有这样做(我可以用队列分配作业并将结果放回另一个队列,但这看起来有点过分)。我喜欢的是,设置节点组很容易(原则上只需指定一个节点,其他节点只能连接到它)。
Simon / RMI - 我想我可以让每个从站向主站注册,然后让主站向每个从站分配作业。或者让每个从站请求一个队列,其中作业排队,一个队列,其中结果应该从主站存储。
Cajo - 原则上可行,但我不想在网格网络上进行多播,而且似乎没有办法解决这个问题。
RabbitMQ - 我不喜欢运行额外的服务器而且它不是纯Java。 ZeroMQ 也是如此。
Akka - 似乎也有点矫枉过正。并且有很多配置来设置节点组。
Hadoop - 像Akka似乎是一种矫枉过正,尤其是设置节点组的配置。
JPPF - 似乎更适合设置长时间运行的服务器和节点群集。我的应用程序完成后,我需要停止所有服务器和节点。此外,它似乎依赖于任务的序列化,这对我来说不是一个选项(见下文)
所以我会坚持使用Hazelcast或Simon。哪一个更适合这种应用?有没有人知道另一个库(不是太重,没有太多的配置)。还有其他建议吗?
Hazelcasts ExecutorService不是btw的选项。因为我正在使用一些JNI,所以序列化会很痛苦。
答案 0 :(得分:0)
我终于和MPJ达成了和解。自定义类加载器的问题可以简单地通过不使用MPJ中包含的脚本来规避,而是直接使用以下参数调用java程序:
java class rank 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慢一点。特别是两者的初始化都相当慢。
答案 1 :(得分: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
类。