2013-07-09 26 views
1

我有一些数据是由0到200万的范围内的IDs键入的,我需要将它分成0-5mil,5mil-10mil等范围的块。Hadoop中的自定义分区程序

我试图使用自定义分区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; 
    } 

} 

b它似乎并没有被调用。即使当我用return 1;替换返回行时,跨文件的数据似乎是使用默认行为散列分布的。你可以这样做

+0

只是好奇你为什么这样接近问题。如果你想根据范围分割你的数据,我相信Pig有内置的命令来帮助你做到这一点。如果你想使用自定义的分区,通过MapReduce而不是Pig更容易吗? – Chaos

+0

恩,好吧,我不知道第一个问题的任何命令。至于第二个问题,我正在考虑,尽管它也可能会显着延迟我的项目学习MapReduce。 – sbilstein

+0

查看我的答案猪指令,可以帮助你做到这一点。 – Chaos

回答

1

答案DISTINCT +自定义分区是:你不能这样做了(因为我刚刚发现)。 DISTINCT现在使用优化的特殊分区程序。

参见:

http://mail-archives.apache.org/mod_mbox/pig-user/201307.mbox/%3C14FE3AC3-DBA5-4898-AF94-0C34819A0D8B%40hortonworks.com%3E

https://issues.apache.org/jira/browse/PIG-3385

一种解决方法:

A = //一些元组...;

B = GROUP BY BY PARTITION BY custom;

STORE B INTO'foo'USING ....;

后来:

B = LOAD'foo'USING ...;

A = FOREACH B GENERATE FLATTEN($ 1);

+0

yea dude我刚刚看到昨天在邮件列表中出现哈哈。谢谢回答。 – sbilstein

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。

您的地图类只会发出对,而您的自定义分区程序会将相应范围的值发送给给定的缩减器。但是,我不确定在对输入数据进行分区后究竟想要做什么,因此我无法评论减速器必须执行的操作。

您可以在Main方法设置自定义分区类为:

Job.setPartitionerClass(<your custom partitioner class>);