Fork me on GitHub

Spark笔记4-RDD运行原理

概念

Hadoop不善于处理迭代场景:逻辑斯蒂回归、模拟退火算法、遗传算法等。MapReduce是将中间结果写入磁盘中,下次使用直接从磁盘中取出来,产生两个问题:

  • 磁盘IO开销大
  • 序列化和反序列化的开销(序列化:将数据对象转成可保存和传输的相应格式,比如Java对象转成二进制或者字符串等)

RDD提供了抽象的数据结构,不必在意底层数据的特性,只需要将数据变成一个个RDD转换,不同的转换之间通过依赖关系,形成了DAG有向无环图。

通过采用一定的优化原理,形成管道化(流水线化)操作,数据不再需要保存在磁盘或者其他存储器中,可以直接进行使用。

RDD是一个分布式对象的集合,本质上是一个只读的分区记录集合,是一个高度受限的共享内存模型。**只有在转换的过程中能够进行修改。**比如,学生的成绩从60分,加5分之后变成65的过程是可以进行修改的。

只能通过生成新的RDD来达到数据修改的目的

操作

两种主要类型的操作如下,它们都是粗粒度的操作:只支持对RDD中所有的数据进行操作,不支持向数据库那样的单条数据的操作。

  • Action:动作类型操作
  • Transformation:转换类型操作

Spark中提供了各种RDDAPI,程序员可以通过调用API来实现对RDD的各种操作。

惰性调用机制

转换过程不会真正产生数据的输出,只记录转换的轨迹,只有通过动作类型的操作才会发生计算,产生最终的结果。

流水线优化

从输出产生的结果不会写入磁盘中,直接持久化到RDD.cache()中再进行输出,避免了不必要的磁盘开销。

特性

  • 只读:本身不能修改,只能通过转换进行数据修改
  • 粗粒度:一次性全集操作
  • 高效的容错性
  • 避免不必要的序列化和反序列化

RDD之间的依赖关系

在实际中一个应用application被分成多个作业task,一个task被分成多个阶段stage,一个阶段是多个任务task的集合。

一个作业为什么要分成多个阶段stage?

shuffle操作

**是否包含shuffle操作(洗牌操作)**是区分宽依赖和窄依赖的关键。只要发生了shuffle操作,一定是发生了很多数据的来回分发动作。数据一定会被写入磁盘中,其中发生等待操作,则无法发生流水线的操作。

窄依赖:不断加入阶段,可以进行流水线操作

宽依赖:必须划分多个阶段,发生了shuffle操作,不能进行流水线操作

窄依赖

没有进行shuffle操作,表现为一个父RDD分区对应为一个子RDD分区或者多个RDD分区对应一个子RDD分区。

总结:只能有一个子RDD分区

宽依赖

产生了shuffle操作,一个父RDD分区对应多个子RDD分区


Spark优化原理

优化是通过fork/join机制。多个分区通过fork并行执行转化操作,再通过join操作

优化栗子

宽依赖中,shuffle操作发生(数据的写磁盘和等待操作),产生数据来回转换并发生等待,则无法流水线化操作。

去掉在上海的join过程,管道化处理:

RDD运行原理全过程

  • 将写的代码提交给整个Spark框架,生成有向无环图DAG
  • DAG提交给DAG Scheduler,分解成多个阶段,每个阶段包含多个任务task
  • 每个任务分配给Task Scheduler,Task Scheduler将任务分发给工作节点WorkerNode上的Excutor进程
  • 通过Excutor进程派发的每个线程去执行任务

Spark部署方式

主要有单机部署集群部署两种方式,集群部署的3中方式包含:

  • StandaloneSpark自带的集群管理器,效率不高
  • YARN:目前最常用的方式
  • Mesos:性能匹配好

Spark和MapReduce是对等的关系,已经取而代之

本文标题:Spark笔记4-RDD运行原理

发布时间:2019年10月23日 - 20:10

原始链接:http://www.renpeter.cn/2019/10/23/Spark%E7%AC%94%E8%AE%B04-RDD%E8%BF%90%E8%A1%8C%E5%8E%9F%E7%90%86.html

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

Coffee or Tea