hadoop自定义分区器的行为不符合逻辑

v1uwarro  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(407)

基于这个例子,这是可行的。在我的数据集上也尝试过同样的方法。
示例数据集:

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

将每行视为字符串,我的Map器输出为:
键->字符串[2],值->字符串。
我的分区代码:

@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。减速器-2。我期望有两个输出文件,一个用于137176,另一个用于剩余的id。我得到两个输出文件,但是,id平均分布在两个输出文件上。我的程序出了什么问题?

raogr8fs

raogr8fs1#

在要使用自定义分区器的驱动程序方法中显式设置,方法是: job.setPartitionerClass(YourPartitioner.class); . 如果不这样做,则使用默认的hashpartitioner。
更改字符串比较方法 ==.equals() . i、 例如,改变 if(keyStr == "137176") {if(keyStr.equals("137176")) { .
为了节省一些时间,也许在分区器的开头声明一个新的文本变量会更快,如下所示: Text KEY = new Text("137176"); 然后,不必每次都将输入键转换为字符串,只需将其与 KEY 变量(再次使用 equals() 方法)。但也许这些是等价的。所以,我的建议是:

Text KEY = new Text("137176");

@Override
public int getPartition(Text key, Text value, int reducersDefined) {
    return key.equals(KEY) ? 0 : 1 % reducersDefined;    
}

另一个建议是,如果网络负载很重,将map输出键解析为vintwritable,并相应地更改分区器。

相关问题