为什么要设计RDD
基于内存的计算可以避免反复的磁盘读写,提高运算效率。spark提出了RDD(Resilient Distributed Datasets)用于支持内存计算。
- RDD是一个只读的数据集,也就是说RDD只能新建,不能修改。所以,这也就导致了RDD的转换是非常重要的。RDD提供了比HadoopMR更加丰富的操作符,这位DAG的创建打下了基础。
- Map
- Reduce
- Fliter
- ……
- RDD本质上存储数据的方式是分布式的。
- 都是粗粒度的操作。也就是说对一个集合采用相同的处理方式。而没有办法去处理其中的元素。但是,功能还是十分强大。
- 这些RDD操作接口非常简单。
RDD的操作,更加丰富。
在Hadoop MapReduce中只有Map和Reduce两种接口。在spark中,这种功能进行了扩展,提供了更加丰富的功能(API接口)。这个转换操作为迭代式并行计算提供了可能和基础。
RDD操作可以被分为两大类:(1)动作 action;(2)转换 transformation。
DAG = (RDD的执行过程)
RDD一般是通过读入外部数据源来创建。他会分布式地保存到很多台机器上面。
RDD通过转换操作来获得新的RDD从而推进整个算法。这些操作首先会被解析,但是不执行,会被解析成一个DAG。这个DAG最后会被一个动作(action)触发。这种情形称为惰性机制。
RDD的特性
1 DAG
生成一张有向无圈图。根据有向无圈图进行计算。
DAG使其天生具有容错性。现有的容错机制有两种:(1)检查点(2)日志。
(1)检查点对于分布式系统代价很高。
(2)日志规模大,代价高。
DAG记录了整个算法,而不是记录计算结果。如果任何中间一步的计算出现问题,可以根据这个DAG算法局部的重新算一遍。相较的,不需要在所有节点重新算一遍。
2 中间结果放在内存中。
避免磁盘的I/O开销
3 RDD本身就是Java对象。
避免了不必要的对象序列化与反序列化。
RDD的依赖关系。
依赖分为宽依赖和窄依赖。依赖的类型非常重要,这涉及到是否要在集群中交换数据。
窄依赖基本在本地执行,是收敛型的。
宽依赖,是放射型的。宽依赖需要shuffle操作。洗牌。
stage的划分
DAG还需要进一步拆分,阶段的拆分以宽依赖为标准。宽依赖之前进行并行计算,宽依赖时数据要进行聚合。也就是说并行计算的局部完成。stage的功能就是将整个任务拆分成合理执行单元。分而治之。
总结
- DAG和stage的划分提高了计算效率,类似非同步的并行机制。
- 新建RDD–>spark context生成DAG–> DAG scheduler负责进一步拆分成stage–>stage中的tasks被 task scheduler发送到各个work node进行工作。