我正在运行一个使用mapreduce的rfm分析程序。outputkeyclass是text.class,我发出逗号分隔的r(recent)、f(frequency)、m(monetory)作为reducer的键,其中r=biginteger、f=binInteger、m=bigdecimal,值也是表示客户id的文本。我知道hadoop会根据键对输出进行排序,但我的最终结果有点奇怪。我希望输出键先按r排序,然后按f排序,然后按m排序。但由于未知原因,我得到了以下输出排序顺序:
545,1,7652 100000
545,23,390159.402343750 100001
452,13,132586 100002
452,4,32202 100004
452,1,9310 100007
452,1,4057 100018
452,3,18970 100021
但我想要以下输出:
545,23,390159.402343750 100001
545,1,7652 100000
452,13,132586 100002
452,4,32202 100004
452,3,18970 100021
452,1,9310 100007
452,1,4057 100018
注意:customer\u id是map阶段的键,属于特定customer\u id的所有rfm值都在reducer中聚集在一起进行聚合。
1条答案
按热度按时间xwbd5t1u1#
因此,经过大量的搜索,我找到了一些有用的资料,我现在正在发布这些资料的汇编:
必须从自定义数据类型开始。因为我有三个逗号分隔的值,需要按降序排序,所以我必须创建一个
TextQuadlet.java
hadoop中的数据类型。我之所以要创建一个quadlet,是因为键的第一部分是自然键,其余三部分是r,f,m:接下来,您将需要一个自定义分区器,以便具有相同键的所有值都在一个缩减器中结束:
第三,您需要一个自定义的组比较程序,以便所有值都按其自然键(即
customer_id
而不是复合键customer_id,R,F,M
:第四,您将需要一个密钥比较器,它将再次根据r、f、m逐次对密钥进行排序,并实现中使用的相同排序技术
TextQuadlet.java
. 因为我在编码时迷路了,所以我稍微改变了在这个函数中比较数据类型的方式,但是底层逻辑与TextQuadlet.java
:最后,在驱动程序类中,必须包含我们的自定义类。这是我用过的
TextQuadlet,Text
作为k-v对。但你可以根据自己的需要选择其他课程请纠正我,如果我在技术上出错的地方,在代码或解释,因为我已经根据这个答案纯粹是我个人的理解,从我在互联网上读到的,它对我的作品完美。