1

我是 Java 和 Hadoop 的新手。我正在尝试一个非常简单的程序来获得频繁对。

例如

Input: My name is Foo. Foo is student. 
Intermediate Output:
    Map:
        (my, name): 1
        (name ,is): 1
        (is, Foo): 2 // (is, Foo) = (Foo, is) 
        (is, student)

所以最后它应该给频繁的pair is (is ,Foo)

伪代码如下所示:

Map(Key: line_num, value: line)
words = split_words(line)
for each w in words:
     for each neighbor x:
          emit((w, x)), 1)

在这里,我的钥匙不是一个,而是一对。在浏览文档时,我读到对于每个新键,我们必须实现WritableComparable

所以我对此感到困惑。如果有人可以解释这门课,那就太好了。不确定这是不是真的。然后我可以自己弄清楚如何做到这一点!

我不想要任何代码,既不映射器也不想要任何东西......只想了解这个 WritableComparable 做什么?WritableComparable 的哪个方法实际上比较了键?我可以看到 equals 和 compareTo,但我找不到任何解释。请不要代码!谢谢

编辑 1:在 compareTo 中,我为对 (a, b) = (b, a) 返回 0 但仍然不会使用相同的减速器,在 compareTo 方法中有什么方法可以将键 (b, a) 重置为 (a, b ) 或生成全新的密钥?

编辑 2:我不知道生成新密钥,但在 compareTo 更改逻辑中,它运行良好..!谢谢大家!

4

2 回答 2

2

WritableComparable是一个接口,它使实现它的类成为两件事:Writable,这意味着它可以通过序列化等方式从您的网络写入和读取。如果您要将它用作键或值以便它可以在 Hadoop 节点之间发送。而且Comparable,这意味着必须提供方法来显示给定类的一个对象如何与另一个对象进行比较。这在 Reducer 通过键组织时使用。

当您想创建自己的对象作为键时,此接口是必需的。您需要创建自己的InputFormat,而不是使用 Hadoop 附带的其中之一。这可能会变得相当困难(根据我的经验),特别是如果您不熟悉 Java 和 Hadoop。

所以如果我是你,我不会为此烦恼,因为有一个更简单的方法。我会使用TextInputFormat既方便又方便的默认设置InputFormat以及非常易于使用和理解。您可以简单地将每个键作为Text与字符串非常相似的对象发出。不过有一个警告;就像您提到的那样"is Foo""Foo is"需要评估为相同的键。因此,对于您提取的每一对单词,在将它们作为键传递给该String.compareTo方法之前,请按字母顺序对其进行排序。这样你就可以保证没有重复。

于 2012-09-27T19:13:40.443 回答
0

这是您的问题的映射器类,没有实现频繁的单词对逻辑。我想你不是在找那个。

public class MR {

public static class Mapper extends org.apache.hadoop.mapreduce.Mapper<LongWritable, Text, Text, LongWritable>
{
    public static int check (String keyCheck)
    {
        // logig to check key is frequent or not ?
        return 0;
    }
    @Override
    protected void map(LongWritable key, Text value, Context context)
            throws IOException, InterruptedException {
        Map< String, Integer> keyMap=new HashMap<String, Integer>();
        String line=value.toString();
        String[] words=line.split(" ");
        for(int i=0;i<(words.length-1);i++)
        {
            String mapkeyString=words[i]+","+words[i+1];
            // Logic to check is mapKeyString is frequent or not .
            int count =check(mapkeyString);
            keyMap.put(mapkeyString, count);

        }
        Set<Entry<String,Integer>> entries=keyMap.entrySet();
        for(Entry<String, Integer> entry:entries)
        {
            context.write(new Text(entry.getKey()), new LongWritable(entry.getValue()));
        }

    }

}
public static class Reduce extends Reducer<Text, LongWritable, Text, Text>
{

    protected void reduce(Text key, Iterable<LongWritable> Values,
            Context context)
            throws IOException, InterruptedException {

    }

}
public static void main(String[] args) {
    Configuration configuration=new Configuration();
    try {
        Job job=new Job(configuration, "Word Job");
        job.setMapperClass(Mapper.class);
        job.setReducerClass(Reduce.class);
        job.setInputFormatClass(TextInputFormat.class);
        FileInputFormat.setInputPaths(job, new Path(args[0]));
        FileOutputFormat.setOutputPath(job, new Path(args[1]));
        job.waitForCompletion(true);


    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (ClassNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}
于 2012-09-28T07:54:28.790 回答