Hadoop自定义分区程序不符合逻辑

时间:2015-07-20 13:09:23

标签: java hadoop mapreduce partitioner

基于此示例here,这可行。在我的数据集上尝试了相同的操作。

示例数据集:

OBSERVATION;2474472;137176;
OBSERVATION;2474473;137176;
OBSERVATION;2474474;137176;
OBSERVATION;2474475;137177;

将每一行视为字符串,我的Mapper输出为:

  

键 - > string [2],value->字符串。

我的分区代码:

@Override
public int getPartition(Text key, Text value, int reducersDefined) {

    String keyStr = key.toString();
    if(keyStr == "137176") {
        return 0;
    } else {
        return 1 % reducersDefined;
    }
}

在我的数据集中,大多数id为137176. Reducer声明为-2。我期待两个输出文件,一个用于137176,第二个用于剩余的Id。我得到两个输出文件,但Id均匀分布在两个输出文件上。我的计划出了什么问题?

1 个答案:

答案 0 :(得分:0)

  1. 使用:job.setPartitionerClass(YourPartitioner.class);在驱动程序方法中明确设置要使用自定义分区程序的方法。如果您不这样做,则使用默认的HashPartitioner。

  2. 将字符串比较方法从==更改为.equals()。即,将if(keyStr == "137176") {更改为if(keyStr.equals("137176")) {
    为了节省一些时间,也许在分区器的开头声明一个新的Text变量会更快:Text KEY = new Text("137176");然后,不用每次都将输入键转换为String,只需将它与{ {1}}变量(再次使用KEY方法)。但也许那些是等价的。所以,我建议的是:

    Text KEY = new Text("137176");
    
    @Override
    public int getPartition(Text key, Text value, int reducersDefined) {
        return key.equals(KEY) ? 0 : 1 % reducersDefined;    
    }
    
  3. 另一个建议是,如果网络负载很重,则将地图输出密钥解析为VIntWritable并相应地更改分区程序。