我的要求是编写一个自定义分区器。我有这 N 个来自映射器的键,例如('jsa','msa','jbac')。长度不固定。事实上,它可以是anyword。我的要求是以这样的方式编写一个自定义分区器,它将所有相同的关键数据收集到同一个文件中。键数不固定。先感谢您。
谢谢,萨西什。
因此,您有多个映射器正在输出的键,并且您希望每个键都有不同的减速器,并且每个键都有一个单独的文件。
因此,首先编写 Partitioner 可能是实现这一目标的一种方式。默认情况下,hadoop 有自己的内部逻辑,它在键上执行,并根据它调用减速器。因此,如果您想编写自定义分区程序,则必须通过您自己的逻辑/算法覆盖该默认行为。除非您知道您的密钥将如何变化,否则此逻辑不会是通用的,并且您必须根据变化找出逻辑。
我在这里为您提供了一个示例示例,您可以参考它,但它不是通用的。
public class CustomPartitioner extends Partitioner<Text, Text>
{
@Override
public int getPartition(Text key, Text value, int numReduceTasks)
{
if(key.toString().contains("Key1"))
{
return 1;
}else if(key.toString().contains("Key2"))
{
return 2;
}else if(key.toString().contains("Key3"))
{
return 3;
}else if(key.toString().contains("Key4"))
{
return 4;
}else if(key.toString().contains("Key5"))
{
return 5;
}else
{
return 7;
}
}
}
这应该可以解决您的问题。只需将 key1,key2 ..etc 替换为您的密钥名称...
如果您不知道键名,可以参考以下内容编写自己的逻辑:
public class CustomPartitioner<Text, Text> extends Partitioner<K, V>
{
public int getPartition(Text key, Text value,int numReduceTasks)
{
return (key.toString().charAt(0)) % numReduceTasks;
}
}
在上面的分区器中,只是为了说明如何编写自己的逻辑,我已经表明,如果您取出键的长度并使用减速器数量进行 % 操作,那么您将获得一个唯一的数字,该数字介于 0 到减速器数量之间所以默认情况下,不同的减速器被调用并在不同的文件中给出输出。但是在这种方法中,您必须确保不应该为两个键写入相同的值
这是关于自定义分区器的。
另一种解决方案是您可以覆盖 MultipleOutputFormat 类方法,这些方法将使您能够以通用方式完成工作。同样使用这种方法,您将能够为 hdfs 中的减速器输出文件生成自定义文件名。
注意:确保使用相同的库。不要将 mapred 与 mapreduce 库混合使用。org.apache.hadoop.mapred 是旧库,org.apache.hadoop.mapreduce 是新库。
希望这会有所帮助。
我想这样做的最好方法是:
public class CustomPartitioner<Text, Text> extends Partitioner<K, V>
{
public int getPartition(Text key, Text value,int numReduceTasks)
{
return key.hashCode() % numReduceTasks;
}
}