How does Spark aggregate function - aggregateByKey work?

前端 未结 2 1707
情歌与酒
情歌与酒 2020-11-29 17:41

Say I have a distribute system on 3 nodes and my data is distributed among those nodes. for example, I have a test.csv file which exists on all 3 nodes and it contains 2 col

2条回答
  •  再見小時候
    2020-11-29 18:03

    aggregateByKey() is quite different from reduceByKey. What happens is that reduceByKey is sort of a particular case of aggregateByKey.

    aggregateByKey() will combine the values for a particular key, and the result of such combination can be any object that you specify. You have to specify how the values are combined ("added") inside one partition (that is executed in the same node) and how you combine the result from different partitions (that may be in different nodes). reduceByKey is a particular case, in the sense that the result of the combination (e.g. a sum) is of the same type that the values, and that the operation when combined from different partitions is also the same as the operation when combining values inside a partition.

    An example: Imagine you have a list of pairs. You parallelize it:

    val pairs = sc.parallelize(Array(("a", 3), ("a", 1), ("b", 7), ("a", 5)))
    

    Now you want to "combine" them by key producing a sum. In this case reduceByKey and aggregateByKey are the same:

    val resReduce = pairs.reduceByKey(_ + _) //the same operation for everything
    resReduce.collect
    res3: Array[(String, Int)] = Array((b,7), (a,9))
    
    //0 is initial value, _+_ inside partition, _+_ between partitions
    val resAgg = pairs.aggregateByKey(0)(_+_,_+_)
    resAgg.collect
    res4: Array[(String, Int)] = Array((b,7), (a,9))
    

    Now, imagine that you want the aggregation to be a Set of the values, that is a different type that the values, that are integers (the sum of integers is also integers):

    import scala.collection.mutable.HashSet
    //the initial value is a void Set. Adding an element to a set is the first
    //_+_ Join two sets is the  _++_
    val sets = pairs.aggregateByKey(new HashSet[Int])(_+_, _++_)
    sets.collect
    res5: Array[(String, scala.collection.mutable.HashSet[Int])]  =Array((b,Set(7)), (a,Set(1, 5, 3)))
    

提交回复
热议问题