7.Action行动算子
转换算子 起始就是记录了数据的一个操作流程 RDD1->RDD2->RDD3->RDD4 , 流式运算现象
RDD1 到 RDD4 之间维护血缘关系(操作行为)
RDD的转换算子是lazy加载 , 不执行行动算子 , RDD根本没有计算数据
只有执行行动算子才会触发RDD去读取数据 (分区:task) 分布式进行运算 JOB
RDD 是spark抽象出来的运算逻辑,RDD中是不存储数据的,只记录数据的操作和RDD之间的血缘关系,只有执行到行动算子的时候才会处理真正的数据
7.1 takeSample
takeSample()函数和上面的sample函数是一个原理,但是不使用相对比例采样,而是按设定的采样个数进行采样,同时返回结果不再是RDD,而是相当于对采样后的数据进行Collect(),返回结果的集合为单机的数组。
object TakeSampleFunction {
def main(args: Array[String]): Unit = {
val sc: SparkContext = SparkUtils.getSparkContext
val rdd1: RDD[Int] = sc.parallelize(1 to 10, 3)
// 行动算子 返回值 不是算子
/**
* 参数一 参数二 获取样本数据的个数
*/
val arr: Array[Int] = rdd1.takeSample(false, 3, 1)
for (elem <- arr) {
println(elem)
}
sc.stop()
}
}
7.2 collect
collect,将数据以数组形式收集回Driver端,数据按照分区编号有序返回
collect是Action里边的,根据RDD的惰性机制,真正的计算发生在RDD的Action操作。由于collect是从各节点将数据拉到driver端,需要重新分区,所以,一次collect就会导致一次Shuffle,而一次Shuffle调度一次stage,然而一次stage包含很多个已分解的任务碎片Task。这么一来,会导致程序运行时间大大增加,属于比较耗时的操作,即使是在local模式下也同样耗时,一般把数据写道Hbase中或者Mysql中都是从executor中往里面写
def main(args: Array[String]): Unit = {
val sc: SparkContext = SparkUtil.getSparkContex