我遇到以下问题:我有大量的键值对数据。关键是一些id和值 - 一些文本。我的目标是将这些对象分组,其中文本片段在某种程度上是“相似的”。因此,如果将我的文本片段作为键,并将id作为值,它看起来像MapReduce的任务。但是这些键并不是MapReduce使用的传统方式,而且我并不是真正意识到MapReduces框架的内部实现,我不确定这种方式是否有效。所以我的想法是: 1.在Java中使用一些MapReduce(Hadoop,GridGain) 2.为我的文本片段创建特殊类(比如TextKey) 3.覆盖类的equals(),在这里打包文本比较逻辑(比如levenstein距离比较,或者其他) 4.覆盖compareTo()以允许MapReduce按键排序(比如词典顺序) 5.可能覆盖hashCode() 6.将我的数据映射到键值对:键 - >文本片段,打包在TextKey类中,值 - > IDS 7.通过收集每个“相等”(实际上相似)密钥的ID来简单地减少
MapReduce可以这样工作吗?
答案 0 :(得分:3)
在GridGain中,可以通过将文本键存储在分区数据网格中轻松解决。 GridGain Data Grid将根据键自动对整个集群中的数据进行分区,因此只要您的类似文本块正确实现标准java hashCode()和equals(),您就可以了。
您还可以在GridGain中发送基于亲缘关系的MapReduce任务,以确保您的作业最终与数据位于同一节点上,以避免在您需要对数据进行某些计算时进行冗余数据移动。这可以通过执行GridProjection.affinityRun(...)方法来实现。
答案 1 :(得分:0)
在地图阶段之后,其输出将使用分区程序进行分区(默认情况下为HashPartitioner,但您可以提供自己的Parititioner)。您的TextKey应该实现LSH hashCode,以便类似的Text值可能会转到同一个分区。
如果键是字符串/文本对象,默认的排序器将起作用,但我认为这不会影响您描述的方案的结果。
问题在于Grouper将分区内的每个组传递给单个reduce调用。默认情况下,这个分组器遍历按此时分类的分区,并且它形成具有相等值的组。在您的情况下,您应该确保分组不是通过相等而是通过相似性来完成的。所以,你的TextKey也应该实现compareTo()
方法,如果LSH hashCodes是相同的,请注意返回0。
总之,您可以使用默认数据路径(即默认的分区程序,分拣程序,Grouper),但您的TextKey(应该实现WritableComparable)应该在hashCode()
和compareTo()
方法中发挥作用< / p>