我想写一个 map reduce 来比较 hdfs 中的两个大文件。任何想法如何实现这一目标。或者如果由于文件大小非常大而没有其他方法进行比较,那么认为 map-reduce 将是一种理想的方法。谢谢你的帮助。
3 回答
您可以分两步进行。
- 首先使行号成为文本文件的一部分:
说初始文件如下所示:
I am awesome
He is my best friend
现在,将其转换为如下内容:
1,I am awesome
2,He is my best friend
这可以通过 MapReduce 作业本身或其他一些工具来完成。
2. 现在编写一个 MapReduce 步骤,其中在 mapper 中发出行号作为键,并将实际句子的其余部分作为值。然后在减速器中只比较值。当它不匹配时,会发出行号(密钥)和有效负载,无论您在这里想要什么。此外,如果计数values
仅为 1,那么它也是不匹配的。
编辑:更好的方法
更好的是,您可以做的是,只需在映射器中一次读取完整的行作为键并将值设为数字,例如 1。因此,以我上面的示例为例,您的映射器输出如下:
< I am awesome,1 >
< He is my best friend,1 >
在 reducer 中只需检查 的计数values
,如果不是 2,则说明不匹配。
但是这种方法有一个问题,如果有可能在两个不同的地方出现完全相同的行values
,那么您应该检查它是否是 2 的倍数,而不是检查 reducer 中给定键的长度。
一种可能的解决方案是将行号作为地图作业中的计数。有两个文件,如下所示:
文件 1:我在这里 -- 第 1 行我很棒 -- 第 2 行 你是我最好的朋友 -- 第 3 行
文件2也是类似的
现在您的地图作业输出应该是,<我很棒,2>...
一旦你完成了这两个文件的 Map 作业,你就有两个记录(键,值),它们具有相同的值来减少。
在 reduce 时,您可以比较计数器或生成输出为 ,依此类推。如果该行也存在于不同的位置,则输出可能表明该行不匹配。
我有一个将文件与密钥进行比较的解决方案。在您的情况下,如果您知道您的 ID 是唯一的,则可以将 ID 作为映射中的键发出,整个记录作为值发出。假设您的文件具有 ID,Line1 然后作为键和映射器的值发出。
在 shuffle 和 sort 阶段,ID 将被排序,您将获得一个包含来自两个文件的数据的迭代器。即,来自具有相同 ID 的两个文件的记录将在相同的迭代器中结束。
然后在化简器中,比较来自迭代器的两个值,如果它们匹配,则继续下一条记录。否则,如果它们不匹配,则将它们写入输出。
我已经做到了,它就像一个魅力。
场景 - 没有匹配的键 如果两个文件之间没有匹配的 ID,它们将只有一个迭代器值。
场景 2 - 重复键 如果文件有重复键,则迭代器将有超过 2 个值。
注意:只有在迭代器只有 2 个值时才应该比较这些值。**提示:**迭代器的值不会总是按顺序排列。要识别来自特定文件的值,请在映射器中在行尾添加一个小指示符,例如 Line1;file1 Line1;file2 然后在 reducer 上,您将能够识别哪个值属于哪个映射器。