如何在分布式机器上划分一个非常大的单词列表搜索以获得更快的答案
How to partition a very large word list search on distributed machine for quicker answer
这更像是一个架构问题,您将如何大规模解决这个问题。
假设您有一个包含数百万个单词的列表,您需要搜索这数百万个单词是否存在于数万亿个单词的语料库中。
例如:
Word_List =
["This", "a", "test", "of", "two", "words","what","words"]
The_corpus =
["This", "a", "test", "of", "two", "words","what","words","blah","blah2"]
在上面的示例中,word_list 中的所有单词都在 the_corpus 中找到,因此我们的函数将 return 为真。请注意 "words" 必须出现两次。
我想知道我们可以通过 Hadoop 或 Spark 解决这个问题,通过在集群上分布 the_corpus 并编写 Mapper 和 Reducer 来检查该词是否存在于语料库中,但我不知道如何 word_list 将分发。我无法在主节点上保留 word_list,因为它太大了。
您可以在 hadoop 中的 hdfs 上添加 word_list 和语料库,这将在所有节点上分发这两个文件。现在您可以从 hdfs 读取这两个文件。在您的映射器代码中,您可以使用文件系统 class 从映射器代码中的 hdfs 访问 word_list 文件。你可以在 Hadoop jar 命令的输入文件路径中提及你的语料库文件。
您的任务具有与普通连接操作相似的目的。在实施它时,您可以考虑某些事项:
- 您可以使用基于 Word_List 的 Bloom 过滤器来缩小 The_corpus 中潜在值的范围collection
- 对于次要 collection 通常使用分布式缓存来使资源在所有任务节点上可用。在您的情况下,这应该是一个很好的 space 命中,因为它将被复制到将执行实际任务的每个节点。为了改善这一点,您可以将文件直接放入具有更大复制因子的文件系统中,例如 10(取决于集群中的节点数),以提高其可用性。然后在您的任务中,您将能够直接下载它,与分布式缓存方法相比,这将显着节省您的 space,但成本将是您在 non-local 读取中的带宽。您可以尝试使用它来找到最佳复制次数。
word_list可以通过Hadoop's DistributedCache机制跨节点分发。本质上,在初始作业配置阶段指定一个文件(-s),然后将其物理复制到将 运行 映射任务的所有节点。然后每个map任务都可以访问和使用这个文件的内容。
因此,您的示例任务在 Hadoop 中通过以下方式解决:word_list 和 corpus 被放入 HDFS ;在作业中 word_list 设置为使用 DistributedCache 分布在所有节点上;在 map 阶段 word_list 针对 corpus 的特定拆分进行检查(即每个 map 任务有 word_list 语料库 的完整和 64/128/...MB 分割,其中 64/128/... 由为 [= 设置的 HDFS 块大小定义18=]语料库 个文件);在 reduce 阶段需要聚合发生,例如如果只返回 True/False 则 reducers 输入可能是 word_list 中所有单词的出现次数:如果所有单词至少出现一次,则为 True、False否则。
一般来说,这种任务被称为map-side加入。请参阅一些示例代码(使用 DistributedCache),例如 here.
猜猜你的问题是如何使用以某种方式在集群节点之间分区的语料库来加速搜索。在这里,我概述了我要做什么。
对语料库进行排序并删除重复项,但为每个单词添加一些重复项,例如 a 1, blah 1, blah2 1, of 1, test 1, this 1, two 1, what 1,words 2等等,可能每行一个词来简化搜索过程或者以某种打包的形式来加速IO。
将语料分成N个部分,记录每个部分单词的字母范围,例如part 1的单词从a到aff,part2的单词从afg到amp等,把所有的parts在每个节点可访问的共享存储上。
排序word_list(并去除重复但添加每个单词的计数)并将单词分为M组M个节点并将每个组分配给一个节点进行搜索。
对每个节点上的每个单词进行二进制搜索(因为单词是排序的)(搜索工具根据字母范围知道要搜索哪个语料库部分)并报告为真(如果所有找到具有正确计数的单词)或错误(一旦一个单词失败就可以 return )。当然,由您决定什么是热门。可以对搜索进行优化。例如,如果一个节点被分配了三个单词 test, this 和 two 的组,并且单词 test 在 part x 的中间找到,则搜索单词 this 将只需要在 part 的右半部分进行x.
这更像是一个架构问题,您将如何大规模解决这个问题。
假设您有一个包含数百万个单词的列表,您需要搜索这数百万个单词是否存在于数万亿个单词的语料库中。
例如:
Word_List =
["This", "a", "test", "of", "two", "words","what","words"]
The_corpus =
["This", "a", "test", "of", "two", "words","what","words","blah","blah2"]
在上面的示例中,word_list 中的所有单词都在 the_corpus 中找到,因此我们的函数将 return 为真。请注意 "words" 必须出现两次。
我想知道我们可以通过 Hadoop 或 Spark 解决这个问题,通过在集群上分布 the_corpus 并编写 Mapper 和 Reducer 来检查该词是否存在于语料库中,但我不知道如何 word_list 将分发。我无法在主节点上保留 word_list,因为它太大了。
您可以在 hadoop 中的 hdfs 上添加 word_list 和语料库,这将在所有节点上分发这两个文件。现在您可以从 hdfs 读取这两个文件。在您的映射器代码中,您可以使用文件系统 class 从映射器代码中的 hdfs 访问 word_list 文件。你可以在 Hadoop jar 命令的输入文件路径中提及你的语料库文件。
您的任务具有与普通连接操作相似的目的。在实施它时,您可以考虑某些事项:
- 您可以使用基于 Word_List 的 Bloom 过滤器来缩小 The_corpus 中潜在值的范围collection
- 对于次要 collection 通常使用分布式缓存来使资源在所有任务节点上可用。在您的情况下,这应该是一个很好的 space 命中,因为它将被复制到将执行实际任务的每个节点。为了改善这一点,您可以将文件直接放入具有更大复制因子的文件系统中,例如 10(取决于集群中的节点数),以提高其可用性。然后在您的任务中,您将能够直接下载它,与分布式缓存方法相比,这将显着节省您的 space,但成本将是您在 non-local 读取中的带宽。您可以尝试使用它来找到最佳复制次数。
word_list可以通过Hadoop's DistributedCache机制跨节点分发。本质上,在初始作业配置阶段指定一个文件(-s),然后将其物理复制到将 运行 映射任务的所有节点。然后每个map任务都可以访问和使用这个文件的内容。
因此,您的示例任务在 Hadoop 中通过以下方式解决:word_list 和 corpus 被放入 HDFS ;在作业中 word_list 设置为使用 DistributedCache 分布在所有节点上;在 map 阶段 word_list 针对 corpus 的特定拆分进行检查(即每个 map 任务有 word_list 语料库 的完整和 64/128/...MB 分割,其中 64/128/... 由为 [= 设置的 HDFS 块大小定义18=]语料库 个文件);在 reduce 阶段需要聚合发生,例如如果只返回 True/False 则 reducers 输入可能是 word_list 中所有单词的出现次数:如果所有单词至少出现一次,则为 True、False否则。
一般来说,这种任务被称为map-side加入。请参阅一些示例代码(使用 DistributedCache),例如 here.
猜猜你的问题是如何使用以某种方式在集群节点之间分区的语料库来加速搜索。在这里,我概述了我要做什么。
对语料库进行排序并删除重复项,但为每个单词添加一些重复项,例如 a 1, blah 1, blah2 1, of 1, test 1, this 1, two 1, what 1,words 2等等,可能每行一个词来简化搜索过程或者以某种打包的形式来加速IO。
将语料分成N个部分,记录每个部分单词的字母范围,例如part 1的单词从a到aff,part2的单词从afg到amp等,把所有的parts在每个节点可访问的共享存储上。
排序word_list(并去除重复但添加每个单词的计数)并将单词分为M组M个节点并将每个组分配给一个节点进行搜索。
对每个节点上的每个单词进行二进制搜索(因为单词是排序的)(搜索工具根据字母范围知道要搜索哪个语料库部分)并报告为真(如果所有找到具有正确计数的单词)或错误(一旦一个单词失败就可以 return )。当然,由您决定什么是热门。可以对搜索进行优化。例如,如果一个节点被分配了三个单词 test, this 和 two 的组,并且单词 test 在 part x 的中间找到,则搜索单词 this 将只需要在 part 的右半部分进行x.