我想构建一个hadoop应用程序,它可以从一个文件中读取单词并在另一个文件中搜索。
如果单词存在 - 它必须写入一个输出文件 如果该单词不存在 - 它必须写入另一个输出文件
我在hadoop中尝试了几个例子。我有两个问题
两个文件各约200MB。检查另一个文件中的每个单词可能会导致内存不足。有没有其他方法可以做到这一点?
如何将数据写入不同的文件,因为hadoop的reduce阶段的输出只写入一个文件。是否可以使用过滤器来减少相位以将数据写入不同的输出文件?
谢谢。
答案 0 :(得分:8)
我该怎么做:
你最终会得到与不同的< missingsources>一样多的reduce-outputs,每个包含文档的缺失单词。你可以写出< missingsource>在'reduce'开头的ONCE标记文件。
(* 1)如何找出地图中的来源(0.20):
private String localname;
private Text outkey = new Text();
private Text outvalue = new Text();
...
public void setup(Context context) throws InterruptedException, IOException {
super.setup(context);
localname = ((FileSplit)context.getInputSplit()).getPath().toString();
}
public void map(Object key, Text value, Context context)
throws IOException, InterruptedException {
...
outkey.set(...);
outvalue.set(localname);
context.write(outkey, outvalue);
}
答案 1 :(得分:1)
您是否因特定原因使用Hadoop / MapReduce来解决此问题?这听起来比Hadoop更适合基于Lucene的应用程序。
如果你必须使用Hadoop,我有一些建议:
您的'文档'需要采用MapReduce可以处理的格式。最简单的格式是基于CSV的文件,文档中的每个单词都在一行上。 PDF等不起作用。
要将一组单词作为输入提供给MapReduce作业,以便与MapReduce处理的数据进行比较,您可以使用Distributed Cache使每个映射器构建一组您想要查找的单词在输入中。但是如果你的单词列表很大(你提到200MB)我怀疑这会起作用。这种方法是您在MapReduce中进行连接的主要方法之一。
此处另一个答案中提到的索引方法也提供了可能性。同样,索引文档的术语只是让我想到Lucene而不是hadoop。如果您确实使用了此方法,则需要确保键值包含文档标识符以及单词,以便您在每个文档中包含单词计数。
我认为我从来没有从MapReduce作业中生成多个输出文件。您需要编写一些(并且这将是非常简单的)代码来将索引输出处理为多个文件。
答案 2 :(得分:0)
在我看来,你会分两个阶段来做这件事。对两个初始文档运行wordcount程序(包含在hadoop示例jar中),这将为您提供两个文件,每个文件包含每个文档中单词的唯一列表(带有计数)。从那里,而不是使用hadoop做两个文件的简单差异,应该回答你的问题,