如何优化hadoop作业中的混洗/排序阶段



我正在使用单节点hadoop作业进行一些数据准备。我的作业中的映射器/组合器输出了许多密钥(超过5M或6M),显然作业进展缓慢甚至失败。映射阶段最多运行120个映射器,只有一个减少器(这些是自动确定的,我没有为它们设置任何值)。我想优化作业,以便更有效地进行混洗/排序阶段。我将mapreduce.task.io.sort.mb增加到300m,但作业失败了,因为它的值大于mapper堆。然后我将mapred.child.java.opts设置为-Xmx1024m,但它再次失败,因为它无法初始化输出收集器。这些场景的最佳实践是什么?

首先,由于您使用的是单节点集群,因此您无法进行太多优化。单个节点集群上的容器/插槽数量有限,并且由于您正在处理的数据量(500万到600万个密钥),您的作业将始终运行缓慢,也可能失败。

我将为一个完全分布式的Hadoop设置回答这个问题。在"Hadoop最终指南"一书中有一节("Shuffle and Sort"),您应该阅读它来调整Shuffle和Sort阶段。我的回答主要受本节内容以及我自己调整MapReduce作业的经验的影响。

您可以执行以下操作以实现无序排列和排序效率:

  • 组合器:使用组合器将减少传输到每个缩减器的数据量,因为组合器在映射器端合并输出
  • 减速器数量:选择最佳减速器数量。如果数据大小很大,那么一个缩减器不是一个好主意。此外,将缩减器的数量设置为较高的数量也不是一个好主意,因为缩减器的数目还决定了映射器端的分区数量。请查看此处的链接:https://github.com/paulhoule/infovore/wiki/Choosing-the-number-of-reducers
  • 何时启动减速器:;您可以控制reduce任务何时启动。这是由YARN中的配置mapreduce.job.reduce.slowstart.completedmaps确定的。在完成一定百分比的映射程序之前,它不会启动减速器。默认情况下,它设置为"0.05"(这意味着减速器在完成5%的映射后启动)。如果减速器提前启动,则大多数减速器处于空闲状态,直到所有映射器完成。此外,减速器可能会占用插槽,否则映射器可能会使用这些插槽进行处理。通过控制这一点,您可以最佳地使用映射器/减速器插槽,并改善混洗过程中花费的时间
  • 压缩映射器输出:建议压缩映射器的输出(由配置决定:mapreduce.map.output.compress),以便将较少的数据写入磁盘并传输到减速器
  • Tune-config"mapreduce.task.io.sort.mb":增加映射程序在排序过程中使用的缓冲区大小。这将减少泄漏到磁盘的次数
  • Tune-config"mapreduce.dreduce.input.buffer.%":如果reduce任务对内存的要求较低,则可以将此值设置为高百分比。这意味着,在reduce阶段(在shuffle阶段之后)使用更大量的堆来保留映射输出,从而减少了溢出到磁盘的次数
  • Tune-config"mapreduce.reduced.shuffle.sparallelco副本":用于将映射输出复制到reducers的线程数。查看此处的链接:如何调整mapred.reduce.paralle.copies

以下是其他配置参数,可以对其进行调整以提高无序播放和排序阶段的性能(请参阅此处对这些配置的描述:https://hadoop.apache.org/docs/r2.4.1/hadoop-mapreduce-client/hadoop-mapreduce-client-core/mapred-default.xml):

  • mapreduce.map.sort.spill.percent:确定映射程序使用的内存中缓冲区的阈值。当达到该阈值时,缓冲区的内容将溢出到磁盘。所以这个值决定了溢出到磁盘的次数
  • mapreduce.task.io.sort.factor:在排序过程中,一次要合并的流的最小数量。因此,在reducer方面,如果有50个映射器输出,并且该值设置为10,则将有5轮合并(平均10个文件用于合并)
  • mapreduce.shuffle.max.threads:用于将映射输出复制到减速器的工作线程数
  • mapreduce.reduce.shuffle.input.buffer.percent:在reducer中的shuffle阶段,应该使用多少堆来存储映射输出。此设置确定映射器输出在溢出到磁盘之前可以保留在内存中的数量
  • mapreduce.reduce.shuffle.merge.percent:开始合并并溢出到磁盘的过程的阈值
  • mapreduce.reduce.merge.inmem.threshold:启动合并过程所需的映射输出数。当达到mapreduce.reduce.shuffle.merge.percentmapreduce.reduce.merge.inmem.threshold时,映射输出被合并并溢出到磁盘

默认情况下,mapreduce只选择一个reducer,这将是大多数场景的问题。

您可以通过将减速器的数量设置为更高的值job.setNumReduceTasks(24); 来更改代码

或运行hadoop jar <jarfilename> <class> -Dmapreduce.job.reduces=24 <parameters>

您需要了解您的数据,才能准确地确定减少的次数。Mapreduce框架根据拆分大小选择映射器的数量,但reduce应由开发人员或操作团队明确设置。

相关内容

  • 没有找到相关文章

最新更新