【发布时间】:2016-01-11 21:47:48
【问题描述】:
我用 Java 编写了一个简单的 Map/Reduce 程序,用于两个文本文件的关系连接操作。该算法在许多地方都有描述,即在 Reduce 任务中进行连接。
我想调整它以获得更好的性能。首先是尝试不同数量的 Reduce 任务。目前我只在一台 4 核的计算机上运行,但实际上是在分布式文件系统中运行。
我遇到了一个奇怪的现象,如果我运行 4 或 32 个 reduce 任务,wall-time(时间统计到时间完成)甚至比我只运行 1 个 reduce 任务的时间长一点:
1 reducer: 22.4 seconds
4 reducer: 23.3 seconds
32 reducer: 26.1 seconds
通过观察这种趋势,我无法真正解释。第一印象是瓶颈会在I/O,因为我是单机运行,高I/O操作并没有真正并行。但是通过查看 CPU stat,i/o 等待时间非常小(在我的测试数据中,输入数据只有几个兆字节),所以它看起来不是一个很好的解释。
要提一提的是,我在运行 map/reduce 程序时监控不同核心的 CPU 使用率,我发现大部分时间 CPU 使用率仅限于一个核心,并且看起来不太像并行.
我还怀疑运行更多 reducer 的好处会被额外的 map/reduce 开销所抵消。
您对此有何看法?
[更新] 我发现在单个 JVM 中,map 和 reduce 任务只能串行运行而不是多线程运行的语句(也通过一些时间观察证明)。这将解释为什么结果是更多的 reducer 任务的时间。
我看到Hadoop使用MultithreadedMapper类支持多线程映射器,我尝试了,不幸的是结果再次变得更糟。
但是不知道为什么会有一个叫MultithreadedMapper的类,但是为什么还有一个像MultithreadedReducer这样的类呢?
【问题讨论】:
-
你确定不用你的代码就能回答这个问题吗?
-
我可以在这里发布代码。只是觉得这是一个普遍的问题,但特定于我的代码。
标签: java performance hadoop join mapreduce