有人能指出一个简单的,开源的Map / Reduce框架/ API for Java吗?似乎没有太多证据证明存在这样的事情,但其他人可能知道不同。
我能找到的最好的当然是Hadoop MapReduce,但这不符合“简单”标准。我不需要能够运行分布式作业,只需要让我在一个JVM中使用标准的Java5风格并发在多核机器上运行map / reduce-style作业。
写自己并不难,但我宁愿不必这样做。
答案 0 :(得分:18)
您有结帐Akka吗?虽然akka实际上是一个基于分布式Actor模型的并发框架,但只需很少的代码就可以实现很多东西。将工作分成几部分非常容易,它可以自动充分利用多核机器,并能够使用多台机器来处理工作。与使用线程不同,我感觉更自然。
我有一个使用akka的Java map reduce example。这不是最简单的地图缩减示例,因为它利用了期货;但它应该让你大致了解所涉及的内容。我的地图缩小示例演示了几个主要内容:
如果您有任何疑问,StackOverflow实际上有一个很棒的akka QA部分。
答案 1 :(得分:11)
我认为值得一提的是,这些问题是Java 8的历史。例如:
int heaviestBlueBlock =
blocks.filter(b -> b.getColor() == BLUE)
.map(Block::getWeight)
.reduce(0, Integer::max);
换句话说:单节点MapReduce在Java 8中可用。
答案 2 :(得分:10)
我使用以下结构
int procs = Runtime.getRuntime().availableProcessors();
ExecutorService es = Executors.newFixedThreadPool(procs);
List<Future<TaskResult>> results = new ArrayList();
for(int i=0;i<tasks;i++)
results.add(es.submit(new Task(i)));
for(Future<TaskResult> future:results)
reduce(future);
答案 3 :(得分:8)
我意识到这可能是事后的一点,但你可能想看一下JDK7的JSR166y ForkJoin类。
有一个支持JDK6的后端移植库,没有任何问题,所以你不必等到下一个千年才能使用它。它位于原始执行程序和hadoop之间,为当前JVM中的map reduce工作提供框架。
答案 4 :(得分:6)
如果你没有得到任何真正的答案,我可以分享更多,但其核心是:
public class LocalMapReduce<TMapInput, TMapOutput, TOutput> {
private int m_threads;
private Mapper<TMapInput, TMapOutput> m_mapper;
private Reducer<TMapOutput, TOutput> m_reducer;
...
public TOutput mapReduce(Iterator<TMapInput> inputIterator) {
ExecutorService pool = Executors.newFixedThreadPool(m_threads);
Set<Future<TMapOutput>> futureSet = new HashSet<Future<TMapOutput>>();
while (inputIterator.hasNext()) {
TMapInput m = inputIterator.next();
Future<TMapOutput> f = pool.submit(m_mapper.makeWorker(m));
futureSet.add(f);
Thread.sleep(10);
}
while (!futureSet.isEmpty()) {
Thread.sleep(5);
for (Iterator<Future<TMapOutput>> fit = futureSet.iterator(); fit.hasNext();) {
Future<TMapOutput> f = fit.next();
if (f.isDone()) {
fit.remove();
TMapOutput x = f.get();
m_reducer.reduce(x);
}
}
}
return m_reducer.getResult();
}
}
编辑:根据评论,以下是没有sleep
的版本。诀窍是使用CompletionService
,它基本上提供了已完成Future
的阻塞队列。
public class LocalMapReduce<TMapInput, TMapOutput, TOutput> {
private int m_threads;
private Mapper<TMapInput, TMapOutput> m_mapper;
private Reducer<TMapOutput, TOutput> m_reducer;
...
public TOutput mapReduce(Collection<TMapInput> input) {
ExecutorService pool = Executors.newFixedThreadPool(m_threads);
CompletionService<TMapOutput> futurePool =
new ExecutorCompletionService<TMapOutput>(pool);
Set<Future<TMapOutput>> futureSet = new HashSet<Future<TMapOutput>>();
for (TMapInput m : input) {
futureSet.add(futurePool.submit(m_mapper.makeWorker(m)));
}
pool.shutdown();
int n = futureSet.size();
for (int i = 0; i < n; i++) {
m_reducer.reduce(futurePool.take().get());
}
return m_reducer.getResult();
}
我还会注意到这是一个非常精简的map-reduce算法,包括一个同时执行reduce和merge操作的reduce worker。
答案 5 :(得分:5)
我喜欢在Java中使用Skandium来实现并行性。该框架为具有共享内存的多核机器实现了某些并行模式(即Master-Slave,Map / Reduce,Pipe,Fork和Divide&amp; Conquer)。这种技术被称为“算法骨架”。模式可以嵌套。
详细说明有骷髅和肌肉。肌肉做实际的工作(分裂,合并,执行和条件)。骷髅代表并行度的模式,除了“While”,“For”和“If”,这在嵌套模式时很有用。
可以在框架内找到示例。我需要一点了解如何使用肌肉和骨骼,但在克服了这个障碍之后我真的很喜欢这个框架。 :)
答案 6 :(得分:3)
你看过GridGain吗?
答案 7 :(得分:3)
您可能需要查看功能4 Java的项目网站:http://f4j.rethab.ch/它在8之前引入了filter,map和reduce到java版本。
答案 8 :(得分:0)
在Hazelcast的v3.2中引入了MapReduce API(参见MapReduce API section in the docs)。虽然Hazelcast旨在用于分布式系统,但它在单节点设置中运行良好,而且相当轻巧。
答案 9 :(得分:0)
您可以尝试LeoTask:运行并行任务和结果聚合框架
它是免费的,开源的:https://github.com/mleoking/leotask
以下是显示其API的简要介绍:https://github.com/mleoking/leotask/blob/master/leotask/introduction.pdf?raw=true
它是一个轻量级框架,使用所有可用的CPU内核在一台计算机上运行。
它具有以下功能:
和实用程序: