我试图了解setOutputValueGroupingComparator方法进行二次排序的必要性 - setPartitioner不会足够吗?
假设我的输入文件包含以下字段:customerId,orderId,orderDate,orderAmount
预期输出为每个客户的最后订单
我使用setOutputKeyComparatorClass()设置了一个关键比较器,它将通过 customerId asc,orderDate desc
进行比较使用setPartitioner()的分区程序将按 customerId%numPartition
进行分区以下是如果减速器数量为2,将发送的示例键:
key1: { customerId : 1, orderDate : 2012-01-31 } => reducer 1
key2: { customerId : 1, orderDate : 2011-12-31 } => reducer 1
key3: { customerId : 2, orderDate : 2011-12-01 } => reducer 2
key4: { customerId : 3, orderDate : 2012-02-01 } => reducer 1
我的问题是:
a)仅使用上述分区器,是否可以按以下(错误)顺序将密钥发送到reducer 1?此处客户3与客户1交错
key1: { customerId : 1, orderDate : 2012-01-31 } => reducer 1
key4: { customerId : 3, orderDate : 2012-02-01 } => reducer 1
key2: { customerId : 1, orderDate : 2011-12-31 } => reducer 1
b)如果是,设置setOutputValueGroupingComparator(比较密钥中的customerId)是否会修复此问题并将其以正确的顺序发送给reducer?
key1: { customerId : 1, orderDate : 2012-01-31 } => reducer 1
key2: { customerId : 1, orderDate : 2011-12-31 } => reducer 1
key4: { customerId : 3, orderDate : 2012-02-01 } => reducer 1
由于
Ajai
答案 0 :(得分:2)
首先,请阅读:http://hadoop.apache.org/common/docs/r0.20.2/mapred_tutorial.html
分区程序决定哪些键转到哪个reducer。因此,如果你有密钥A,B,C和D,以及减速器1和2,那么分区器决定输出A和C(例如)进入减速器1,而B和D进入减速器2。
OutputKeyComparatorClass确定在缩减之前是否以及如何使用相同的键对不同的行进行排序。 Shuffle阶段仅按分组按键输出Map - 它不保证数据已排序。
在您的情况下,您似乎选择了错误的密钥。我认为您的密钥应该是{customerId,orderDate},您应该使用getOutputValueGroupingComparator来比较customerId仅用于分组的密钥,并使用setOutputKeyComparatorClass来比较按customerId和orderDate降序的密钥以输入到reducer。另见Owen O'Malley关于同一主题的电子邮件:http://www.mail-archive.com/core-user@hadoop.apache.org/msg05677.html