我的问题是关于RDD上groupBy()
操作的替代/优化。我有数百万Message
个实例需要根据某些ID进行分组。我使用groupBy()
来完成目标但我知道这是一个昂贵的事实,它需要大量的处理时间。
所以我尝试reduceByKey(func)
和combineByKey()
作为替代方案,这是我在一些资源中提出的,但它不符合我的情况
我的要求只是分组 。但是我的数据量很大,groupBy
消耗的能力超过我工作时间的70%。因此,任何建议或解决方案都表示赞赏。
我的输入数据
Seq(新消息(“1”,“abc”,“请求”),新消息(“1”,“cba”, “响应”),新消息(“2”,“def”,“请求”),新消息(“2”, “fed”,“Response”),新消息(“3”,“ghi”,“Request”),new 消息(“3”,“ihg”,“响应”))
为简单起见,我在Seq
def groupMessages(sourceRdd: RDD[Message]): Unit {
val messageIdRdd = sourceRdd.mapPartitions(partitionData => {
partitionData.map(row => (row.uniqueID(), row))
})
/*
Group messages based on its message id. This functionality is to combine request response
together as single transaction based on message id.
*/
val groupbyRdd = messageIdRdd.groupBy(_._1)
}
预期结果
(2,CompactBuffer((2,消息(2,DEF,请求)), (2,消息(2,进料,响应)))) (3,CompactBuffer((3,消息(3,GHI,请求)), (3,消息(3,洲际,响应)))) (1,CompactBuffer((1,消息(1,ABC,请求)), (1,消息(1,CBA,响应))))
答案 0 :(得分:0)
您应该使用groupByKey()而不是groupBy()来在集群中执行。
scala> myRDD.map(x=>x).groupBy(_._1).take(10).foreach(println)
(2,CompactBuffer((2,def,Request), (2,fed,Response)))
(3,CompactBuffer((3,ghi,Request), (3,ihg,Response)))
(1,CompactBuffer((1,abc,Request), (1,cba,Response))))
您的groupBy()是:
scala> myRDD.map(x=>(x._1,x)).groupByKey().take(10).foreach(println)
(2,CompactBuffer((2,def,Request), (2,fed,Response)))
(3,CompactBuffer((3,ghi,Request), (3,ihg,Response)))
(1,CompactBuffer((1,abc,Request), (1,cba,Response))
groupByKey()代码为:
tokenizer(scanner)
希望它有所帮助。
答案 1 :(得分:-1)
如果您的要求只是分组,则可以使用groupByKey()。如果要进行聚合(sum,avrage等),可以使用reduceByKey()或combinedByKey()。 reduceByKey()和combinedByKey()之间的主要区别是返回类型。 reduceByKey()返回类型应与值类型匹配,但在combinedByKey()中可能不同。当您的回复看起来只对分组感兴趣时,您可以选择groupByKey()。