Spark API 之 aggregate(a)(fun1,fun2)

java面试题网站:www.javaoffers.com

aggregate是一个 柯里化函数,首先我们知道一个rdd有可能为多个partition。

a: 相对于fun1 作用于每个partition中的元素的第一个元素,即为每个partition增加一个首元素a,  相对于fun2 作用于  每个partition经过fun1后对应的结果 和 a 

fun1 : 作用于Rdd中的每个partition,并且遍历执行每个partition中的元素(此时的元素已经增加了a),类似于java中的List集合进行for循环遍历每个元素,并在for循环中执行fun1 函数,

fun2: 作用于 a 和 每个partition经过fun1后对应的结果(组成新的并列,a永远在第一个元素)并 遍历计算,

demo1:

       val a = sc.parallelize(List("a","b","c","d"),2)  // sc 为sparkContext对象

       a.aggregate("8")(_+_,_+_)

       输出结果为:"88ab8cd"

demo2:

       val a = sc.parallelize(List(2,4,6,2,14,6),2)

       a.aggregate(3)(math.max(_,_),_+_)

       计算过程为:在第一个分区中拿到最大6

                             在第二个分区拿到最大14

                             最后加上一个3

        结果为23

下面我来补充一案例详解他的逻辑:

package relax.sparkApi

import org.apache.spark.{SparkConf, SparkContext}

object sparkApiDemo {

  def main(args: Array[String]): Unit = {
    val sc = new SparkContext(new SparkConf().setMaster("local").setAppName("aggregate"))

//    val rdd1 = sc.parallelize(List(1,2,3,4,5,6),2)
//    val i = rdd1.aggregate(0)(math.max(_,_),_+_)
//    println(i)
//
    var hs =  (a: String,b:Any)=>{  //第一个函数  打印用 :
      println("---------------------")
      println(a+" : "+b)
      a+" : "+b
     }
    var hd = (a:String,b: String)=>{  //第二个函数  打印用 +
      println("---------------------")
      println(a+" + " +b)
      a+" + "+b
    }
    val rdd2 = sc.parallelize(List('1',"2","3","4","5","6"),2) //分两个区
    val str = rdd2.aggregate("i")(hs,hd)//开始执行
    println(str) //打印最终的结果
  }
}

我们来工作console 打印的信息来了解:

18/11/14 19:56:35 INFO BlockManagerInfo: Added broadcast_0_piece0 in memory on localhost:64776 (size: 1162.0 B, free: 3.8 GB)
18/11/14 19:56:35 INFO SparkContext: Created broadcast 0 from broadcast at DAGScheduler.scala:861
18/11/14 19:56:35 INFO DAGScheduler: Submitting 2 missing tasks from ResultStage 0 (ParallelCollectionRDD[0] at parallelize at sparkApiDemo.scala:27)
18/11/14 19:56:35 INFO TaskSchedulerImpl: Adding task set 0.0 with 2 tasks
18/11/14 19:56:35 INFO TaskSetManager: Starting task 0.0 in stage 0.0 (TID 0, localhost, PROCESS_LOCAL, 2141 bytes)
18/11/14 19:56:35 INFO Executor: Running task 0.0 in stage 0.0 (TID 0)
---------------------
i : 1
---------------------
i : 1 : 2
---------------------
i : 1 : 2 : 3                  

 // 第一个分区 通过打印信息得知:第一次执行hs函数,把 'i' 传递给 hs 函数中的a , 把分区中遍历的第一个元素传递给b

 //并且把hs的结果  再次传递给hs函数参数a ,接着遍历分区中的下一个元素传递给b, 直到遍历分区中的所有元素为止 ,

 // 分区中的元素个数代表遍历次数,也代表hs函数的迭代次数,把hs最后一次迭代运行结果返回,作为当前分区的计算结果。
18/11/14 19:56:35 INFO Executor: Finished task 0.0 in stage 0.0 (TID 0). 891 bytes result sent to driver
18/11/14 19:56:35 INFO TaskSetManager: Starting task 1.0 in stage 0.0 (TID 1, localhost, PROCESS_LOCAL, 2099 bytes)
18/11/14 19:56:35 INFO Executor: Running task 1.0 in stage 0.0 (TID 1)
---------------------
i : 4
---------------------
i : 4 : 5
---------------------
i : 4 : 5 : 6                           //第二个分区逻辑同上一样


18/11/14 19:56:35 INFO Executor: Finished task 1.0 in stage 0.0 (TID 1). 891 bytes result sent to driver
---------------------
i + i : 1 : 2 : 3                      

//当所有分区中的元素遍历完毕,也是就hs迭代完毕,则开始执行hd函数,hd函数执行的次数与分区的次数有关

// 把 i 传递给 hd函数中的参数a 然后把第一个分区的结果传给b,得到的新结果再次传递给hd参数的a,遍历下一个分区的结果

//传递给 b, 知道每个分区的每个结果遍历完毕,也就是说hd函数迭代计算的次数与遍历分区结果的次数相同,最后将最终的结果返回 
18/11/14 19:56:35 INFO TaskSetManager: Finished task 0.0 in stage 0.0 (TID 0) in 115 ms on localhost (1/2)
18/11/14 19:56:35 INFO TaskSetManager: Finished task 1.0 in stage 0.0 (TID 1) in 29 ms on localhost (2/2)
18/11/14 19:56:35 INFO DAGScheduler: ResultStage 0 (aggregate at sparkApiDemo.scala:28) finished in 0.144 s
18/11/14 19:56:35 INFO TaskSchedulerImpl: Removed TaskSet 0.0, whose tasks have all completed, from pool 
---------------------
i + i : 1 : 2 : 3 + i : 4 : 5 : 6    

//总结就是 hd的执行逻辑是,i 加(这里的“加, + ” 就是执行一个hd函数)上每一个分区的结果,好比: i + 第一个分区结果+ 第二个分区结果
18/11/14 19:56:35 INFO DAGScheduler: Job 0 finished: aggregate at sparkApiDemo.scala:28, took 0.483809 s


i + i : 1 : 2 : 3 + i : 4 : 5 : 6  //打印最终的结果 对应代码中的  “println(str) //打印最终的结果”


18/11/14 19:56:35 INFO SparkContext: Invoking stop() from shutdown hook
18/11/14 19:56:36 INFO SparkUI: Stopped Spark web UI at http://192.168.17.1:4040
18/11/14 19:56:36 INFO DAGScheduler: Stopping DAGScheduler
18/11/14 19:56:36 INFO MapOutputTrackerMasterEndpoint: MapOutputTrackerMasterEndpoint stopped!
18/11/14 19:56:36 INFO MemoryStore: MemoryStore cleared
18/11/14 19:56:36 INFO BlockManager: BlockManager stopped

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值