我有一些数据是由0到200万的范围内的ID键入的,我需要将其分成0-5mil,5mil - 10mil等范围内的数据。
我试图在Hadoop上使用自定义分区程序来完成最后一部分,以便我的代码的最后一部分看起来像这样:
Conns = FOREACH ConnsGrouped GENERATE group as memberId, $1.companyId as companyIds;
ConnsPartitioned = DISTINCT Conns PARTITION BY com.mypackage.SearchNodePartitioner PARALLEL 50;
rmf $connections_file
Store ConnsPartitioned INTO 'test' using AvroStorage(...);
我的分区看起来像这样:
public class SearchNodePartitioner<Long, V> implements Partitioner<Long, V>
{
@Override
public void configure(JobConf conf)
{
// Nothing
}
@Override
public int getPartition(Long key, V value, int numPartitions)
{
return new Double(Math.floor(key / (5.0 * Math.pow(10, 6)))).intValue() % numPartitions;
}
}
但它似乎根本没有被召唤。即使我用return 1;
替换返回行,跨文件的数据似乎也使用默认行为进行散列分发。
答案 0 :(得分:1)
DISTINCT +自定义分区程序的答案是:你不能再这样做了(正如我刚刚发现的那样)。 DISTINCT现在使用优化的特殊分区器。
请参阅:
https://issues.apache.org/jira/browse/PIG-3385
解决方法:
A = //一些元组......;
B = GROUP A BY字段PARTITION BY custom;
存储进入'foo'使用....;
随后:
B = LOAD'foo'使用......;
A = FOREACH B GENERATE FLATTEN($ 1);
答案 1 :(得分:0)
您可以这样做的一种方法是:
A = LOAD ............
SPLIT A INTO B IF <your range condition> , C IF < your range condition>
STORE B ...
STORE C ...
否则你可以试试这个:
B = FILTER A BY $1 >= <lower_Range> AND $1 <= <upper_Range>;
此外,由于您已经编写了自定义分区程序,因此使用MapReduce可以轻松实现此功能。
您的Map类只会发射对,而您的自定义分区程序会将适当的值范围发送到给定的reducer。但是,一旦您对输入数据进行分区,我不确定您想要做什么,因此我无法评论减速器必须执行的操作。
您可以在Main方法中将自定义分区程序类设置为:
Job.setPartitionerClass(<your custom partitioner class>);