我有一个Pig脚本需要大约10分钟才能完成,我认为还有一些性能提升空间。
所以,我首先将JOIN
和GROUP
置于嵌套FOREACH
中,并将之前的FILTER
置于同一FOREACH
内
我还添加了using 'replicated'
。
现在的问题是,它不需要花费10分钟,而是花费超过30分钟。
除了PIG的文档之外,是否有一个拥有最佳实践和性能改进技巧的地方?
这样你可以得到更好的图片,这里有一些代码:
--before
previous_join = JOIN A by id, B by id --for symplification
filtering = FILTER previous_join BY ((year_min > 1995 ? year_min - 1 : year_min) <= list_year and (year_max > 2015 ? year_max - 1 : year_max) >= list_year);
final_filtered = FOREACH filtering GENERATE user_id as user_id, list_year;
--after
final_filtered = FOREACH (JOIN A by id, B by id) {
tmp = FILTER group BY ((A::year_min > 1995 ? A::year_min - 1 : A::year_min) <= B::list_year and (A::year_max > 2015 ? A::year_max - 1 : A::year_max) >= B::list_year and A::premium == 'true');
GENERATE A::user_id AS user_id, B::list_year AS list_year;
};
我做错了什么或这是错误的做法?
感谢。
答案 0 :(得分:1)
在先前的情况下[之前],您在执行连接后执行过滤和投影。 如果您计算每个操作的时间日志并确定瓶颈操作,将会很有帮助。
您是否也可以尝试将过滤语句拆分为多个关系而不仅仅是一个,并检查过滤时间的差异?
filter_by_min_year = FILTER previous_join BY ((A::year_min > 1995 ? A::year_min - 1 : A::year_min) <= B::list_year);
filter_by_max_year = FILTER filter_by_min_year BY (A::year_max > 2015 ? A::year_max - 1 : A::year_max) >= B::list_year);
总体而言,您希望使用A :: year_min&lt; = B :: list_year和A :: year_max&gt; = B :: list_year找到ID(+更多列) 而不是在原始A&amp; A上执行连接B,您可以尝试在它们两者上使用投影,仅包含连接和后续操作所需的列。
A-projected = foreach A generate id, year_min, year_max;
B-projected = foreach B generate id, list_year;
C = join A-projected by id, B-projected by id USING 'replicated';
如果A投影或B投影中的任何一个是可以在内存中加载的小集合使用复制连接,我假设B投影比A投影小。 如果这不适用于您的情况,请跳过此选项。
您也可以尝试使用PARALLEL关键字设置要用于此连接的缩减器数量。
应用过滤器后,您将获得所需ID的列表,您可以使用该列表从A或B中获取其他信息。
另外考虑调整MapReduce属性,如io.sort.mb,mapred.job.shuffle.input.buffer.percent等。
希望这有帮助。