前言
spark算子的执行位置 driver端 还是executor端,这些之前其实没有注意过,最近在学流处理,发现这个还是很重要的,今天专门讲一下,只有好好理解了这些,针对业务才能开发出更好的代码。
具体测试
driver 和executor的作用
driver是运行用户编写Application 的main()函数的地方,具体负责DAG的构建、任务的划分、task的生成与调度等。
executor是真正执行task地方,而task执行离不开具体的数据,这些task运行的结果可以是shuffle中间结果,也可以持久化到外部存储系统。
具体样例代码
我这边先读取一个csv,转化为强类型后,声明一个map做了些相关的操作,代码如下
val frame = spark.read.csv("file:///E:\\data.csv")
frame.show()
val hashmap = mutable.HashMap[String,Integer]()
frame.as[String].foreach {x=>
if (x.contains("zeng")){
hashmap.put("zeng",1)
println("executor============== "+hashmap.size)
}
}
println("==========================")
println("driver ======================"+hashmap.size)
这里多说一嘴
val hashmap = mutable.HashMapString,Integer
这么去声明一个hashMap (这块写的少,都不太会。。。)
然后在yarn-client上运行,发现
1、executor============== 这个print打印不出来
2、driver ====================== 的hashmap的size为1
解释
第一个executor==============打印不出来的原因是因为 foreach函数针对的是rdd 中的数据,这个具体执行是在executor端,所以日志不会在driver短线是
第二个hashmap的size为0 (data.csv包含zeng这个字符串) 是因为foreach传入的函数变成一个闭包在executor中进行调用,所以内部的hashmap和外部的hashmap就已经没有了关系,所以这个时候size变为0.
所以hashmap这种堆对象,数据库连接等都是这样,不能在rdd的map算子外部声明,内部使用,所有rdd的算子都是如此,所有Dataframe/dataset算子也是如此。
总结
所有对RDD具体数据的操作都是在executor上执行的,所有对rdd自身的操作都是在driver上执行的。
网友评论