Spark RDD 的那些个事事

内容来自京东金融微信公众号整理和解读


Google 发表三大论文  GFS  MapReduce BigTable  衍生出很多开源框架 ,毫无疑问 Hadoop 在 大家心中的地位是不可估量的  。Hadoop 因为其高可用 高扩展 高容错 特性成为开源工业界的事实标准,作为一个可以搭建下廉价PC 机器上的分布式集群体系 ,Hadoop 用户可以不关心底层实现细节 ,利用Hadoop 自动的MapReduce 程序就可以写出运行在分布式上的简单程序 ----分布式应用   。Hadoop MR 的局限性 无法满足循环 以及迭代数据流 ,所以在某些个复杂场景 机器学习 图挖掘计算 交互式数据挖掘算法 并不实用  这些个都要用到高效的计算迭代  在 Hadoop 局限性上 SPark  应用而生  Spark  在 hadoop 在 传统MR 基础上做了优化 ,提高了运行速度 更重要的是将计算单元缩小到更适合并行计算和重复使用的RDD


RDD 是什么 

RDD 是怎么形成的

RDD 的依赖关系

RDD 的内部结构


个人感觉 面试 以上四个问题 就基本可以把大部分给涮下去  成火锅


RDD 是什么 

RDD 是spark 整个 体系中最重要的概念  RDD (Resilient Distributed DataSet) 中文就是 弹性分布式数据集 ,弹性 ----简单解释就是RDD 是可以横向多分区的 ,纵向概念理解起来可能更容易 ,当计算过程中内存不足时候可以把数据刷到磁盘等外部存储上  从而实现 数据在内存和外存的灵活切换。作者在文中解释说个人更偏向 RDD 是有虚拟数据结构组成,并不包含真实数据体  这有点想我们关系型数据库中view 视图 ,只是有结构 没有真实数据 存在 。 RDD 更高的是使用了一种叫‘血统’的容错机制 , 这个词在一般的书籍中看不到 ,也是第一次见有作者这么说  checkpoint   ,这样子可以在结构更新和数据丢失后 根据血统 能够 对数据模型重建 生成 RDD  。所谓 分布式 就是 数据的计算可以在多台计算机上并行同时进行

从空间结构上看  RDD 可以理解 是一组只读的  可分区的的分布式数据集合  一个RDD 包含多个分区  ,分区是依照一定的规则的  ,将具有相同属性的数据记录在一块  。从而每个分区相当于一个数据片段  ,点评 初次从 HDFS上 读取时候 虽然也是分区的 但是 数据并一定具有相同的属性


RDD 是怎么形成的

RDD 的形成  主要是通过  链接屋里存储输入 的数据集  和 在已有的 RDD 计算得到 


val lines = spark.read.textFile("").rdd
val words = lines.flatMpa(_.split(" ")).map(x => (x,1))
val wordcount =words.reduceByKey(_+_)
wordcount.saveAsTextFile("")

解码解析 :

第一行代码 读取一个文件 ,转化成RDD

第二行 按空格 分开 ,并对每个单词计数一

第三行 对有的词进行分组 并 根据单词对单词数进行累加

第四行将wordcount 统计 输出到文件


RDD 的依赖关系   ,依赖关系也 是 计算优于Hadoop 的 一个重要原因

RDD之间的依赖关系中 有两个重要的词  窄依赖  宽依赖


窄依赖  如果一个父RDD 的每个分区可以被子RDD的 一个分区使用   ----> 一对一关系

宽依赖 如果一个父RDD 的每个分区可以被子RDD 的多个分区使用   ----> 一对多关系


弄两个依赖 搞这么麻烦 ,why:


窄依赖从计算过程来看 , 数据是以管道的方式经过一系列的计算操作  运行在一个节点上  如 map  filter 等

相反的

宽依赖 数据可能需要跨节点传输后在计算 ,这个过程成为shuffle  增加了数据传输时间


从数据恢复看 ,窄依赖 更高  因为 只需要找到一个斧RDD 就可以了 ,同时在不同节点上可以并行处理  宽依赖 因为设计到 跨分区的的数据计算  就麻烦多了


根据宽窄依赖 可以引入一个新的概念  stage  , 在个人理解过程中 ,stage  如果在遇到 宽依赖之前 都是一个完整的stage  如果发生了 宽依赖 就会打破 stage 范围


Stage 是由一组RDD组成的可进行优化的执行计划  如果 RDD 的 依赖关系都是 窄依赖 则可以放在一个stage 里面执行 若 RDD 的 依赖关系是宽依赖 则需要放在不同stage 执行  ,这样子 在spark 程序运行时候会根据 stage 划分 ,生成一个完整的最优的执行计划 



RDD 的内部结构 (成为 大牛 必须要讲出来的东西)

RDD 的主要属性 ,rdd name  sparkcontext sparkconf  parent  storageLevel  partitioner check point Iterator

SparkContext  : sparkcontext 为spark job 的入口 ,由是sparkdrvie 创建在client 端 包括集群链接 ,RDDid 创建抽样  累加器 广播变量等

SparkConf   Spark 参数配置信息

Parent  指向依赖上层RDD的partitioner id 利用dependencies 方法可以查找RDD所依赖的partition 的List 集合

StorageLevel  一个枚举类型 用来存储RDD 的 存储级别 ,内存 磁盘 堆外内存 ,另外还包括是否 序列化操作 以及 副本数量

Partitioner  RDD 的分区方式 ,()Hash 和 Range  这两种的分区类型都是 Key vale  ,如果是非 k-v 分区类型是None 

Hash 是以key 作为分区条件的散列分布 ,分区数据不连续   ,可能会导致数据不均 引起 **********************

Range 按key 的排序平衡分布 ,分区内数据连续  大小相对一致


Check Point 

spark 提供的一种缓存机制 ,当需要计算的RDD 过多时候 为了避免重新计算之前的RDD造成 资源浪费 ,可以对 RDD 做 checkpoint  操作 ,检查RDD是否被物化或计算  ,并将结果 持久化,与 spark 提供的另外一种 缓存机制相比 cache ,cache 的缓存数据有 executor 管理 ,所以 executor 如果消逝了 那么 缓存的数据也就没了 RDD 从而重新计算


Iterator  说真的 不是特明天 这个东西是干嘛的

迭代器 用来 查看当前RDD 跟 上层 RDD 的 依赖关系  并通过 storeageLevel 确定存储位置

迭代方式 氛围 checkpoint 和 RDD 迭代

如果StorageLevel 为None 则 执行 computeorReadcheckpoint 方法计算并获取数据 ,迭代checkpoint数据的存放位置  ;如果checkpoint 不为None  根据存储级别 进入相应的RDD 迭代器 继续迭代上层RDD 知道获取数据 位置  。而迭代器内部有本地优化策略 ,先从本地获取数据 ,如果没有则远程查找










 

 














posted @ 2017-03-28 22:09  yuerspring  阅读(126)  评论(0编辑  收藏  举报