我有一个带有一些xml的pig-latin脚本,使用XPath UDF提取一些字段,然后存储结果字段:
REGISTER udf-lib-1.0-SNAPSHOT.jar;
DEFINE XPath com.blah.udfs.XPath();
docs = LOAD '$input' USING com.blah.storage.XMLLoader('root') as (content:chararray);
results = FOREACH docs GENERATE XPath(content, 'root/id'), XPath(content, 'root/otherField'), content;
store results into '$output';
请注意,我们在群集中使用了pig-0.12.0,所以我从pig-0.14.0中删除了XPath / XMLLoader类并将它们放在我自己的jar中,以便我可以在0.12中使用它们
以上脚本运行正常并生成我正在寻找的数据。但是,它会生成超过1,900个partfiles,每个文件只有几个mbs。我了解了default_parallel选项,因此我将其设置为128以尝试获得128个partfiles。我最终不得不添加一块来强制减少阶段来实现这一目标。我的脚本现在看起来像:
set default_parallel 128;
REGISTER udf-lib-1.0-SNAPSHOT.jar;
DEFINE XPath com.blah.udfs.XPath();
docs = LOAD '$input' USING com.blah.storage.XMLLoader('root') as (content:chararray);
results = FOREACH docs GENERATE XPath(content, 'root/id'), XPath(content, 'root/otherField'), content;
forced_reduce = FOREACH (GROUP results BY RANDOM()) GENERATE FLATTEN(results);
store forced_reduce into '$output';
同样,这会产生预期的数据。此外,我现在得到128个部分文件。我现在的问题是数据不是均匀分布在部分文件中。有些人有8场演出,有些有100 mb。当我们用RANDOM()对它们进行分组时,我应该预料到这一点。)。
我的问题是什么是限制零件文件数量的首选方法,但它们仍然具有均匀大小?我是猪/猪拉丁语的新手,并假设我以完全错误的方式解决这个问题。
P.S。我关心零件文件数量的原因是因为我想用spark来处理输出,而且我们的spark集合似乎用较少的文件做得更好。
答案 0 :(得分:0)
我仍在寻找一种直接从pig脚本执行此操作的方法,但是现在我的“解决方案”是在spark脚本的输出中对spark数据进行重新分区。我使用RDD.coalesce
函数来重新平衡数据。
答案 1 :(得分:0)
从第一个代码片段开始,我假设它是map only job,因为你没有使用任何聚合。
不使用reducer,而是设置属性pig.maxCombinedSplitSize
REGISTER udf-lib-1.0-SNAPSHOT.jar;
DEFINE XPath com.blah.udfs.XPath();
docs = LOAD '$input' USING com.blah.storage.XMLLoader('root') as (content:chararray);
results = FOREACH docs GENERATE XPath(content, 'root/id'), XPath(content, 'root/otherField'), content;
store results into '$output';
exec;
set pig.maxCombinedSplitSize 1000000000; -- 1 GB(given size in bytes)
x = load '$output' using PigStorage();
store x into '$output2' using PigStorage();
pig.maxCombinedSplitSize - 设置此属性将确保每个映射器读取大约1 GB的数据,并且上面的代码用作身份映射器作业,这有助于您以1GB的部分文件块写入数据。