如何在Hadoop程序中处理大量映射器的密钥?

时间:2013-10-29 23:02:37

标签: hadoop mapreduce

我的Hadoop程序的映射阶段会生成大量唯一键(一个数据集大约200K键,另一个数据组大约900K)。每个键都是一个包含60个数字字符的字符串值。我的Hadoop程序的排序/重排阶段耗时太长。有没有办法让排序/改组阶段对于如此众多的密钥更有效?

2 个答案:

答案 0 :(得分:0)

你应该考虑使用合成器来减少网络的过热,并将发送到“Reducer”的“map-phase”输出结合起来。

你对于WritableComparator是正确的,最好是实现你的,因为据我所知,在排序阶段比较两个对象的方式是,一旦序列化了对象(从mapper输出),Hadoop为了给定和排序,必须反序列化它们,所以避免“反序列化阶段”并在字节级进行比较要好得多。

compare覆盖方法WritableComparable时必须小心,因为正确地执行此方法非常具有挑战性,我所指的方法来自GrepCode

http://grepcode.com/file/repository.cloudera.com/content/repositories/releases/com.cloudera.hadoop/hadoop-core/0.20.2-737/org/apache/hadoop/io/WritableComparator.java#WritableComparator.compare%28byte%5B%5D%2Cint%2Cint%2Cbyte%5B%5D%2Cint%2Cint%29

修改

我添加了一篇我认为很棒的文章,就改善MapReduce的性能提出了一些建议:

http://blog.cloudera.com/blog/2009/12/7-tips-for-improving-mapreduce-performance/

答案 1 :(得分:0)

您应该创建自定义密钥类型。这有几个原因:

  • 通过使用数字(二进制​​)密钥,您可以实现Comparable<BinaryComparable>,它可以比较字节而不是文本,从而提高速度
  • 您可以将密钥写为二进制格式,这样可以节省传输和读取密钥的时间。如果我们要编写一个密钥类,我们可以扩展BytesWritable,它已经实现了我在第一个项目符号中提到的接口。

您应该调整一些作业参数。例如,您可能需要考虑调整作业中的io.sort选项。因为你有很多独特的值,Hadoop可能无法在内存中对它们进行排序,这意味着它必须溢出到磁盘。发生这种情况时,必须重新读取和重新排序数据,从而减慢随机播放的速度。由于记录了溢出,您可以通过查看日志来判断是否发生溢出。有关优化提示,请参阅http://www.slideshare.net/cloudera/mr-perf