我的要求是编写一个自定义分区程序。例如,我有N个键来自mapper ('jsa','msa','jbac')。长度不是固定的。事实上,它可以是任何一个词。我的要求是编写一个自定义分区程序,使它能够将所有相同的关键数据收集到同一个文件中。键的数量不固定。提前谢谢你。
谢谢,Sathish .
所以你有多个键,mapper输出,你想为每个键不同的reducer,并为每个键有一个单独的文件。
所以首先写Partitioner可以达到这个目的。默认情况下,hadoop有自己的内部逻辑,它在键上执行,并根据它调用reducer。因此,如果您想编写自定义分区器,那么您必须使用自己的逻辑/算法覆盖默认行为。除非你知道你的键是如何变化的,否则这个逻辑不会是通用的,你必须根据变化找出逻辑。
我在这里提供了一个示例,您可以参考它,但它不是通用的。
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…
如果您不知道键名,您可以通过参考以下内容编写自己的逻辑:
public class CustomPartitioner<Text, Text> extends Partitioner<K, V>
{
public int getPartition(Text key, Text value,int numReduceTasks)
{
return (key.toString().charAt(0)) % numReduceTasks;
}
}
在上面的分区中,只是为了说明你如何编写自己的逻辑,我已经表明,如果你拿出键的长度并对reducers的数量进行%操作,你将得到一个唯一的数字,它将在0到reducers的数量之间,因此默认情况下不同的reducers被调用并在不同的文件中给出输出。但是在这种方法中你必须确保对于两个键相同的值不能写成
这是关于自定义分区。
另一种解决方案是,您可以覆盖MultipleOutputFormat类方法,使您能够以通用的方式完成该工作。同样,使用这种方法,您将能够为hdfs中的reducer输出文件生成自定义文件名。
注意:请确保使用相同的库。不要将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;
}
}