Spark 学习中的一些疑问
Spark
学习中的一些疑问
问题1:Spark
为什么只有在调用 action
时才会触发任务执行呢?
Spark 算子主要划分为两类:transformation 和 action,并且只有 action 算子触发的时候才会真正执行任务。
Spark RDD 的缓存和 checkpoint 是懒加载操作,只有 action 触发的时候才会真正执行,其实不仅是 Spark RDD,在 Spark 其他组件如SparkStreaming 中也是如此,这是 Spark 的一个特性之一。像我们常用的算子 map、flatMap、filter 都是 transformation 算子,而 collect、count、saveAsTextFile、countByKey、foreach 则为 action 算子。
但是,为什么 Spark 任务只有在调用 action 算子的时候,才会真正执行呢?
假设一种情况:假如 Spark 中 transformation 直接触发 Spark 任务!那么会产生什么结果呢?
-
导致 map 执行完了要立即输出,数据也必然要落地(内存和磁盘)
-
map 任务的生成、调度、执行,以及彼此之间的 rpc 通信等等,当牵扯到大量任务、大数据量时,会很影响性能
看到这两点是不是很容易联想到 MapReduce 的计算模型,MapReduce 因为中间结果需要落地,导致性能相对 Spark 较低下,这也是 MapReduce 广为诟病的原因之一。所以 Spark 采用只有调用 action 算子时才会真正执行任务,这是相对于 MapReduce 的优化点之一。
但是每个 Spark RDD 中连续调用多个 map 类算子,Spark 任务是对数据在一次循环遍历中完成还是每个 map 算子都进行一次循环遍历呢?
实际上,并不需要对每个 map 算子都进行循环遍历。Spark 会将多个 map 算子 pipeline 起来应用到 RDD 分区的每个数据元素上
问题2:Spark
与 MapReduce
对比
Spark
-
集流批处理、交互式查询、机器学习及图计算等于一体
-
基于内存迭代式计算,适合低延迟、迭代运算类型作业
-
可以通过缓存共享 rdd、DataFrame,提升效率【尤其是 SparkSQL 可以将数据以列式的形式存储于内存中】
-
中间结果支持 checkpoint,遇错可快速恢复
-
支持 DAG、map 之间以 pipeline 方式运行,无需刷磁盘
-
多线程模型,每个 worker 节点运行一个或多个 executor 服务,每个 task 作为线程运行在 executor 中,task 间可共享资源
-
Spark 编程模型更灵活,支持多种语言如 java、scala、python、R,并支持丰富的 transformation 和 action 的算子
MapReduce
-
适合离线数据处理,不适合迭代计算、交互式处理、流式处理
-
中间结果需要落地,需要大量的磁盘 IO 和网络 IO 影响性能
-
虽然 MapReduce 中间结果可以存储于 HDFS,利用 HDFS 缓存功能,但相对 Spark 缓存功能较低效
-
多进程模型,任务调度(频繁申请、释放资源)和启动开销大,不适合低延迟类型作业
-
MR 编程不够灵活,仅支持 map 和 reduce 两种操作。当一个计算逻辑复杂的时候,需要写多个 MR 任务运行【并且这些 MR 任务生成的结果在下一个 MR 任务使用时需要将数据持久化到磁盘才行,这就不可避免的进行遭遇大量磁盘 IO 影响效率】
- 点赞
- 收藏
- 关注作者
评论(0)