我面临两个问题:
报告文件
我正在生成PIG报告。其输出分为几个文件:part-r-00000,part-r-00001,...(这是由于他的关系相同,只有多个映射器正在生成数据。因此有多个文件。):
B = FOREACH A GENERATE col1,col2,col3;
STORE B INTO $output USING PigStorage(',');
我希望所有这些最终都在一个报告中,所以我最终做的是在使用HBaseStorage
存储结果之前,我正在使用并行1:report = ORDER report BY col1 PARALLEL1
对它们进行排序。换句话说,我将reducers的数量强制为1,因此生成一个文件如下:
B = FOREACH A GENERATE col1,col2,col3;
B = ORDER B BY col1 PARALLEL 1;
STORE B INTO $output USING PigStorage(',');
是否有更好的方法来生成单个文件输出?
分组依据
我有几个报告执行分组:grouped = GROUP data BY col
除非我提到parallel 1
,否则PIG会决定使用多个reducer来对结果进行分组。当我对数据求和或计数时,我得到的结果不正确。例如:
而不是看到这个:
part-r-00000:
grouped_col_val_1, 5, 6
grouped_col_val_2, 1, 1
part-r-00001:
grouped_col_val_1, 3, 4
grouped_col_val_2, 5, 5
我应该看到:
part-r-00000:
grouped_col_val_1, 8, 10
grouped_col_val_2, 6, 6
所以我最终按照以下方式完成了我的小组:grouped = GROUP data BY col PARALLEL 1
然后我看到了正确的结果。
我有一种感觉我错过了什么。
这是一个关于我如何进行分组的伪代码:
raw = LOAD '$path' USING PigStorage...
row = FOREACH raw GENERATE id, val
grouped = GROUP row BY id;
report = FOREACH grouped GENERATE group as id, SUM(val)
STORE report INTO '$outpath' USING PigStorage...
答案 0 :(得分:1)
根据您提供的额外详细信息编辑新答案:
1)不,你描述它的方式是在Pig中唯一的方法。如果要下载(已排序)文件,只需执行hdfs dfs -cat
或hdfs dfs -getmerge
即可。但是,对于HBase,如果使用HBaseStorage的-loadKey=true
选项,则不需要进行额外的排序。我没有试过这个,但是请尝试一下,让我知道它是否有效。
2)不需要PARALLEL 1
。如果这不适合你,我怀疑你的伪代码是不完整的。您使用的是自定义分区程序吗?这是我可以找到结果的唯一解释,因为GROUP BY
使用的默认分区程序会将所有键的实例发送到同一个reducer,从而为您提供所期望的结果。
老答案:
1)您可以使用合并连接而不是仅使用一个reducer。来自Apache Pig documentation:
通常存储用户数据,使得两个输入都已经在连接键上排序。在这种情况下,可以在MapReduce作业的映射阶段加入数据。与通过不需要的排序和混洗阶段传递所有数据相比,这提供了显着的性能提升。
执行此操作的方法如下:
C = JOIN A BY a1, B BY b1, C BY c1 USING 'merge';
2)您不需要使用PARALLEL 1
来获得所需的结果。无论您使用的减速器数量多少,GROUP
都可以正常工作。您能否发布用于案例2的脚本代码?