Spark RDD基本介绍
rdd
RDD(Resilient Distributed Dataset)叫做分布式数据集,Spark中最基本的数据抽象,它代表一个不可变、可分区、里面的元素可并行计算的集合.
rdd是spark的灵魂,中文翻译弹性分布式数据集,一个rdd代表一个可以被分区的只读数据集。rdd内部可以有许多分区(partitions),每个分区又拥有大量的记录(records)。
RDD分类
窄依赖:父RDD只被一个子RDD引用
宽依赖:父RDD被不止一个子RDD引用
rdd的五个特征:
1.dependencies:建立RDD的依赖关系,主要rdd之间是宽窄依赖的关系,具有窄依赖关系的rdd可以在同一个stage中进行计算。
2.partition:一个rdd会有若干个分区,分区的大小决定了对这个rdd计算的粒度,每个rdd的分区的计算都在一个单独的任务中进行。
3.preferedlocations:按照“移动数据不如移动计算”原则,在spark进行任务调度的时候,优先将任务分配到数据块存储的位置
4.compute:spark中的计算都是以分区为基本单位的,compute函数只是对迭代器进行复合,并不保存单次计算的结果。
5.partitioner:只存在于(K,V)类型的rdd中,非(K,V)类型的partitioner的值就是None。
再说几观点:
1.spark程序中,我们用到的每一个rdd,在丢失或者操作失败后都是重建的。
2.rdd更多的是一个逻辑概念,我们对于rdd的操作最终会映射到内存或者磁盘当中,也就是操作rdd通过映射就等同于操作内存或者磁盘。
3.在实际的生产环境中,rdd内部的分区数以及分区内部的记录数可能远比我们想象的多。
4.RDD 本身的依赖关系由 transformation() 生成的每一个 RDD 本身语义决定。
每个 RDD 中的 compute() 调用 parentRDD.iter() 来将 parent RDDs 中的 records 一个个 拉取过来。
算子
算子是RDD中定义的函数
rdd的算子主要分成2类,action和transformation。
这里的算子概念,可以理解成就是对数据集的变换。action会触发真正的作业提交,而transformation算子是不会立即触发作业提交的。每一个 transformation() 方法返回一个 新的RDD。只是某些transformation() 比较复杂,会包含多个子 transformation(),因而会生成多个 RDD。这就是实际 RDD 个数比我们想象的多一些 的原因。通常是,当遇到action算子时会触发一个job的提交,然后反推回去看前面的transformation算子,进而形成一张有向无环图。在DAG中又进行stage的划分,划分的依据是依赖是否是shuffle的,每个stage又可以划分成若干task。接下来的事情就是driver发送task到executor,executor自己的线程池去执行这些task,完成之后将结果返回给driver。action算子是划分不同job的依据。shuffle dependency是stage划分的依据。