如果在传递到reduce阶段时需要为给定键排序值,例如移动平均值,或者模仿SQL中的LAG/LEAD Analytic函数,则需要在MapReduce中实现Secondary Sort.
在Google上搜索后,常见的建议是:
A)发射复合键,其中包括,在映射阶段B)创建一个"复合键比较器"类,其目的是进行二次排序,比较值,在比较键后进行排序,使得Iterable传递给reducer的是排序的.C)创建一个"自然键分组比较器"类,其目的是进行主要排序,仅比较要排序的键,以便传递给reducer的Iterable包含属于给定键的所有值.D)创建一个"自然键分区类",其目的是我不知道并且是我的问题的目的.
从这里:
自然键分区器使用自然键将数据分区到reducer.再次注意,在这里,我们只考虑"自然"键.
通过自然键,他当然意味着实际的键,而不是复合键+值.
从这里:
默认分区将计算整个键的哈希值,从而产生不同的哈希值以及将记录发送到单独的reducer的可能性.为确保将两个记录发送到同一个reducer,我们将实现一个客户分区程序.
从这里:
在真正的Hadoop集群中,有许多减速器在不同的节点中运行.如果同一区域和日期的数据在地图减少洗牌后没有降落在同一个减速器中,我们就遇到了麻烦.确保这一点的方法是负责定义我们自己的分区逻辑.
我提供的每个来源以及我见过的所有其他来源都建议根据以下伪代码编写分区类:
naturalKey = compositeKey.getNaturalKey() return naturalKey.hashCode() % NUMBER_OF_REDUCERS
现在,我的印象是Hadoop保证对于给定的密钥,对应于该密钥的所有值都将被定向到同一个reducer.
我们创建自定义分区程序的原因与我们创建"自然键分组比较器"类相同,以防止MapReduce发送复合键而不是reducer键吗?
Sudarshan.. 5
现在的问题是几乎一样的答案:),你上面提到的一切是正确的,我想解释的概念应该助阵不同的方式为好.
所以让我试一试.
让我们假设我们的辅助排序是做出来的姓氏和名字的组合键.
使用复合键,现在让我们看一下二级排序机制
分区器和组比较器仅使用自然键,分区器使用它将具有相同自然键的所有记录引导到单个reducer.这种分区发生在Map Map中,来自各种Map任务的数据由reducers接收,它们被分组,然后发送到reduce方法.这个分组是组比较器的结果,如果我们不指定自定义组比较器,那么Hadoop将使用默认实现,该实现将考虑整个复合键,这将导致不正确的结果.