Java Mapreduce 排序复合值

Java Mapreduce sort composite value

我有一个映射器,它发出一个文本(水果名称)键和一个自定义复合值 city:count。我想在复合值到达 reducer 之前按计数对其进行排序,以便 reducer 可以快速确定哪个城市的计数最高。

复合值 class 是 WritableComparable 的扩展,具有检索计数和城市的方法。

我的 reducer 目前收到的是什么:

reducer 1 - oranges:<london:2, chicago:15, charleston:6>
reducer 2 - apples:<charleston:31, london:3, chicago:29>
...

我希望我的reducer接收到什么:

reducer 1 - oranges:<chicago:15, charleston:6, london:2>
reducer 2 - apples:<charleston:31, chicago:29, london:3>

从逻辑上讲,我该如何做到这一点?我读过几篇关于 Secondary Sorting/Ordering 的文章,但它们倾向于关注复合键而不是复合值。我的密钥不需要进一步分区,也不需要进一步排序。

同样,按复合值而不是复合键排序!

如果您的目标只是快速确定水果的最高含量,我想推荐另一种方法。由于在大多数情况下排序具有 O(n log n) 的复杂性,而找到最大的条目只有 O(n),其中 n 是您案例中的城市数量。

1.带内存的映射器

您可以在每个映射器中使用哈希图来确定每个映射器中每种水果的最高数量。只需使用 fruit 作为键,将 city+count 作为值。当您拿到水果时,请查看地图以比较更大的水果。如果水果不存在,你显然必须设置它。 当执行所有映射步骤时,框架将调用映射器的清理方法。在清理中,您可以发出地图的条目。这将显着减少您必须在减速器中发送和通过的值的数量。

2。组合器

方法 1. 有一个明显的缺点。如果你有大量不适合内存的水果,它是不可扩展的。如果是这种情况,您可以使用在映射器端执行的组合器。它的工作方式类似于相应映射器提供的较小数据集的缩减器。这也会带来减少您发送到减速器的值数量的好处。

3。二次排序

您可以通过二次订购来完成。我真的很想鼓励您阅读 Preeti Khurana 提供的文章。尤其是answer of Sudarshan。给你一个简单的想法:使用 fruit:count 的复合键和 city:count 的值。请注意,您需要根据密钥的第一部分进行特殊分区。我认为这需要付出很大的努力,但在某些情况下这是有用且必要的。