我正在寻找有关如何提高Pig工作性能的任何技巧。
输入是单个文件 (MB),但对于文件中的每一行,都会执行一个非常占用 CPU 的任务。
因此,理想的做法是在我的 Amazon EMR 集群中的许多映射器(和计算机)中拆分此文件。
但是我找不到一种方法来做到这一点,因为Hadoop自然只会在64(还是128?MB 间隔,所以我只有 1 个映射器!
我已经看过NLineInputFormat(http://www.olenick.com/blog/hadoop-for-small-data/),但这适用于旧的API,也不确定它如何与Pig一起工作。
更复杂的是,我正在使用CSVExcelStorage存钱罐加载函数进行加载。
谢谢
邓肯
已解决。
这需要设置更多参数。 我并不是说您需要设置所有这些,但是我没有时间进行反复试验以查看所需的最小设置。 很高兴得到纠正!
将以下内容放在 pig 脚本的顶部:
SET mapred.max.split.size 131072; -- 128KB
SET mapred.min.split.size 131072;
SET default_parallel 2;
SET pig.noSplitCombination true;
SET mapred.max.jobs.per.node 1;
我已经将我的设置为 128KB 块,因为我的输入真的很小!
此外,设置 dfs 块大小。 在 Amazon EMR 中,通过设置以下 Boostrap 操作来执行此操作:
--hdfs-key-value dfs.block.size=131072
我们可以通过查看输出看到这已经起作用了:
作业统计(以秒为单位的时间):JobId 映射减少 MaxMapTime MinMapTIme 平均地图时间 MaxReduceTime MinReduceTime 平均减少时间 中位数ReduceTime 别名功能输出job_201309111450_0001 14 0 15 9 11 12 0 0 0 0 A,已清洁,无停止MAP_ONLY s3n://mybucket/out42,
所以我们可以看到使用了 14 个映射器。 此外,还生成了 14 个部件(在我的情况下),总运行时间与每条记录的时间相同(在我的情况下为 4 分钟)。
尽量保持输入拆分较小。 设置此属性:
SET mapred.max.split.size 1000; -- or whatever
该数字以字节为单位拆分大小。 例如,如果您有一个 30 MB 的文件并且需要 3000 个映射器,请尝试将最大拆分大小设置为 10000
。
这不是一个详细的解决方案,只是一个大致的想法......
您可以通过在化简阶段(而不是映射阶段)执行 UDF 并使用 PIG 的并行功能来控制化简器的数量来解决此问题。为了给您一个提示,您可以通过以下方式设置脚本的默认化简器数量(例如为 40
):设置default_parallel 40;
强制 UDF 在化简器中运行的一种方法是执行一个 GROUP,然后调用传递每个组的 UDF。
例如
AG = 组 A 乘 X 平行 40;b = FOREACH AG GENERATE yourUdf(a);
一个组需要一个排序阶段,所以组之后的FOREACH将在化简器中运行。
如果您没有好的密钥可供选择,您可以尝试 GROUP a ALL,它可能会起作用。此外,您需要更改 UDF 以接收数据包而不是元组或标量,因为每个组都作为包传递。实施起来可能有点棘手,但一旦完成,它就非常简单而优雅。
如果您的脚本中已经有一个 GROUP,则可以使用该组并保存额外的 map-reduce 作业。还有其他子句也会强制您可能需要考虑的缩减阶段。
大卫