用mapReduce术语表达一个类似grep的算法,用于很长的关键字列表



我很难用mapreduce术语表达算法。

我有两个大的输入文本文件:让我们称第一个文件为"R"和第二个"P"。R 通常比 P 大得多,但两者都很大。

在非mapreduce方法中,P的内容将被加载到中内存(散列),然后我们将开始遍历所有行在R.R 中的行只是字符串,我们希望检查 R 中的任何子字符串是否与 P 中的任何字符串匹配。

这个问题与在大文件中啃咬单词非常相似,这个问题是单词列表非常大,因此您无法对它们进行硬编码在您的地图例程中。

我遇到的问题是我不知道如何确保P 文件的所有拆分最终都会在 R 文件的每个拆分中结束。因此,假设这些拆分:

R = R1, R2, R3;
P = P1, P2

6 个地图作业必须包含以下拆分:

(R1, P1) (R1, P2);
(R2, P1) (R2, P2);
(R3, P1) (R3, P2);

你会如何用mapreduce术语来表达这个问题?

谢谢。

我花了一些时间研究这个问题,我想出了几个解决 方案。第一个基于Hadoop流,第二个使用。原生爪哇。

对于第一个解决方案,我使用了 ruby 中的一个有趣功能。如果添加关键字__END__在代码末尾,之后的所有文本都将由解释器通过全局变量 DATA 公开。此变量是一个文件对象。例:

$ cat /tmp/foo.rb
puts DATA.read
__END__
Hello World!
$ ruby /tmp/foo.rb
Hello World!

我们将使用文件 R 作为输入(它将分布在 HDFS 文件中)。我们遍历 P 文件,遍历一定数量的行后,我们在映射器脚本的末尾添加这些内容。然后,我们将作业提交给Hadoop集群。我们不断迭代 P 的内容,直到我们得到消耗了所有行。多个作业将根据每个作业的行数和 P 的大小。

这是我实施的一个很好的方法,效果很好。我不过不要觉得特别优雅。我们可以通过编写本地版本做得更好Java中的MapReduce应用程序。

当使用原生Java应用程序时,我们可以完全访问HadoopHDFS API。这意味着我们可以从代码中读取文件的内容。那是东西我认为它在流式传输时不可用。

我们遵循类似于流媒体方法的方法,但是一旦我们有遍历了一定数量的行,我们将这些行发送到Hadoop集群将其附加到代码中。我们可以在调度的代码中做到这一点我们的工作。

然后,运行与拆分数量一样多的作业的问题我们有 P.特定作业中的所有映射器将加载某个拆分并将使用它来计算 R 的拆分。

好问题。

我能想到的一种快速方法是将 P 文件拆分为多个文件,并使用 P 文件和完整 R 文件的每个拆分作为输入运行多个 MR 作业。

相关内容

  • 没有找到相关文章

最新更新