我的要求是编写自定义分区程序。我有这些N个键来自mapper(例如'jsa','msa','jbac')。长度不固定。它可以是任意的。我的要求是以这样一种方式编写自定义分区器,它将收集所有相同的密钥数据到同一个文件中。键数不固定。先谢谢你。
谢谢, Sathish所在。
答案 0 :(得分:2)
因此,您有多个映射器正在输出的键,并且您希望每个键都有不同的reducer,并且每个键都有一个单独的文件。
首先编写Partitioner可以成为实现这一目标的方法。默认情况下,hadoop有自己的内部逻辑,它在密钥上执行,并根据它调用reducers。因此,如果您想编写自定义分区程序,则必须使用自己的逻辑/算法覆盖默认行为。除非你知道你的密钥究竟有多么变化,否则这个逻辑不会是通用的,并且根据变化你必须弄清楚逻辑。
我在这里为您提供一个示例示例,您可以参考它,但它不是通用的。
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到0之间减少的数量因此默认情况下会调用不同的减速器并在不同的文件中提供输出。但是在这种方法中,你必须确保两个键不应该写相同的值
这是关于自定义分区程序。
另一种解决方案是,您可以覆盖MultipleOutputFormat类方法,这些方法将允许以通用方式执行作业。同样使用此方法,您将能够为hdfs中的reducer输出文件生成自定义文件名。
注意:确保使用相同的库。不要将mapred与mapreduce库混合使用。 org.apache.hadoop.mapred是较旧的库,org.apache.hadoop.mapreduce是新的。
希望这会有所帮助。
答案 1 :(得分:0)
我想最好的方法就是这样做,因为它可以提供更均匀的分割:
public class CustomPartitioner<Text, Text> extends Partitioner<K, V>
{
public int getPartition(Text key, Text value,int numReduceTasks)
{
return key.hashCode() % numReduceTasks;
}
}