如何在Spark RDD

时间:2016-11-23 13:17:32

标签: java scala apache-spark

我的问题是关于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,响应))))

2 个答案:

答案 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()。