我有一个小项目,我在mapreduce做,因为我是这个新的,我遇到了很多困难,所以我会感谢你的帮助。在这个项目中,我有一个包含站点和标签(每个站点有10个标签)的文件,我想通过共享标签为每个站点找到相似的站点。以3个站点为例,这是我的数据集
site1 tag1
site1 tag2
site1 tag3
site1 tag4
site1 tag5
site2 tag1
site2 tag2
site2 tag3
site2 tag11
site2 tag12
site3 tag1
site3 tag11
site3 tag13
site3 tag14
site3 tag15
(在这个例子中,我为每个站点只做了5个)。我要做的是做一个mapreduce,它的键是站点的标签和值。我想让每个标记都得到一个包含此标记的站点列表(或数组或其他什么),因此在本例中:
tag1: site1, site2, site3
tag2: site1,site2
tag3: site1, site2
tag4: site1
以此类推,然后遍历列表,对于每一个公共对,在它旁边给出一个值1,如下所示
tag1: site1_site2 1, site1_site3 1, site2_site3 1
tag2: site1_site2 1
以此类推,然后链接另一个mapreduce作业,对我为其编写的代码中的每一对的值求和
public static class TokenizerMapper extends Mapper<Object, Text, Text, Text>{
private Text site = new Text();
private Text tag = new Text();
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString(), "\t");
while (itr.hasMoreTokens()) {
site.set(itr.nextToken());
tag.set(itr.nextToken());
context.write(tag, site);
}
}
}
public static class tagCount extends Reducer<Text,IntWritable,Text,Text> {
public void reduce(Text key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
String res = "";
while (values.iterator().hasNext()) {
res = res + "," + values.iterator().next();
}
Text result = new Text(res);
context.write(key, result);
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "tag count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(tagCount.class);
job.setReducerClass(tagCount.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
我的第一个问题是如何将reducer中的值链接在一起?从现在起我只得到一份
tag1 site1
tag1 site2
所以我试着设置一个字符串,当我迭代值向字符串添加下一个标记时,它不起作用
事先非常感谢你的帮助
1条答案
按热度按时间slsn1g291#
下面是你的减速机的重述,让你开始:
总结:
您需要构建一个值的内部集合。在本例中,我使用了字符串列表,这是最安全的方法,直到您熟悉hadoop如何重用对象为止。
此代码假定
sites
不会太大,所以一个改进是在它的大小周围添加一些检查,因为我们将它放在内存中,下面的context.write将扩展数据。然后遍历站点并生成排列,写出每个排列。
把数据写出来
SequenceFileOutputFormat
然后你接下来的工作SequenceFileInputFormat
输入Map器的类型将是Text
以及IntWritable
.