我正在寻找有关如何通过Pig工作提高绩效的任何提示。
输入是单个文件(MB),但对于文件中的每一行,都会执行非常耗费CPU的任务。
所以理想的做法是将这个文件分割到我的Amazon EMR集群中的许多映射器(和机器)上。
但是我找不到办法做到这一点,因为Hadoop自然只能在64(或者是128?)MB间隔分割,所以我只有1个映射器!
我查看了NLineInputFormat(http://www.olenick.com/blog/hadoop-for-small-data/),但这是针对旧的API,也不确定它如何与Pig一起使用。
为了进一步复杂化,我使用CSVExcelStorage piggybank loadfunc加载。
由于
邓肯
答案 0 :(得分:2)
解决。
这需要更多参数设置。我不是说你需要设置所有这些,但我没有时间进行试验和错误,看看最低要求是什么。非常乐意在此纠正!
将以下内容放在猪脚本的顶部:
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 AvgMapTime MedianMapTime MaxReduceTime MinReduceTime AvgReduceTime MedianReducetime别名功能输出 job_201309111450_0001 14 0 15 9 11 12 0 0 0 0 A,cleansed,nostop MAP_ONLY s3n:// mybucket / out42,
所以我们可以看到使用了14个映射器。此外还有14个零件生成(在我的情况下),总运行时间与单个记录的时间相同(在我的情况下为4分钟)。
答案 1 :(得分:1)
尽量保持输入分割尽可能小。设置此属性:
SET mapred.max.split.size 1000; -- or whatever
该数字是以字节为单位的拆分大小。如果您有30 MB的文件并且想要3000个映射器(例如),请尝试将最大分割大小设置为10000
。
答案 2 :(得分:1)
这不是一个详细的解决方案,只是一个普遍的想法......
您可以通过在reduce阶段(而不是map阶段)执行UDF来解决此问题,并使用PIG的并行功能来控制Reducer的数量。为了给你一个提示,你可以设置脚本的默认减速器数量(以40为例):
SET default_parallel 40;
强制UDF在reducer中运行的一种方法是执行GROUP,然后调用传递每个组的UDF。
E.g。
ag = GROUP a BY x PARALLEL 40; b = FOREACH ag GENERATE yourUdf(a);
组需要排序阶段,因此组之后的FOREACH将在reducer中运行。
如果你没有好的钥匙可供选择,你可以尝试GROUP a ALL,它可能会有效。此外,您需要更改UDF以接受DataBag而不是元组或标量,因为每个组都作为包传递。实现它可能有点棘手,但一旦完成它就非常简单和优雅。
如果您的脚本中已有GROUP,则可以使用该组并保存额外的map-reduce作业。还有其他一些条款也强制要求您考虑减少阶段。
大卫