1.5.1.1 Spark-RDD

总目录:https://www.jianshu.com/p/e406a9bc93a9

Hadoop - 子目录:https://www.jianshu.com/p/9428e443b7fd

什么是RDD

在MapReduce中,map会对数据进行切片操作,但是整个过程中充满了序列化,反序列化操作,这回造成大量的磁盘IO占用。
而Spark使用了一种将数据保存在内存中的读写方式,这就大大加快了处理流程,但是大块的数据终究没有小块的消化的快,所以spark也有一个自己的切分数据的操作--RDD。
一个RDD就是一个分布式对象的集合,本质上是一个只读的分区记录的集合。他是一种高度受限的共享内存模型。
他一旦生成,就无法修改,但是可以在转换时发生修改。(将RDD转换成新的RDD)

分布式并行

RDD为什么可以加快运行速度,是因为他把数据分散的存储在了不同的节点上。

RDD的操作类型

RDD有两种操作类型--动作类型操作,转换类型操作。
这两种都是粗粒度的操作,一次作用于一个RDD全集。


粗粒度操作

因为他们是粗粒度操作,所以他不能对数据中一些细微的改变进行操控,这就导致了spark不能进行爬虫操作。

转换操作

RDD典型的执行过程

执行过程

但是这样,如果频繁的对RDD进行读写,也会间接导致RDD执行效率降低,这就引入的了RDD一个关键的机制--惰性机制。


惰性机制

惰性机制是在转换类型过程中,RDD只记录轨迹,不会真正对RDD进行操作,在转换类型过程结束后的动作类型过程中才会发生修改或计算。

流程

我们前面会进行转换,最后才进行动作。

除了惰性机制,还有一个重要的机制--管道化。


管道化

在操作1和操作2中,数据不会写入磁盘,而是直接在内存中完成输入输出。

总结:

  • 高强的容错性

因为spark操作RDD是先记录操作再操作,如果在操作中发生了RDD丢失可以通过寻亲来找到这个RDD的父亲,然后按照记录从新走一遍。

  • 避免不必要的序列化和反序列化

因为RDD是从硬盘中读出,在动作执行完成后再写入磁盘。

RDD的依赖关系

RDD的运行过程为什么要拆分成转换环节和动作环节呢,他拆分的依据是什么,这就是我们RDD的依赖关系。
RDD的依赖关系分为两种,一种叫宽依赖,一种叫窄依赖。


依赖种类

RDD的宽依赖,识别宽依赖很简单,因为宽依赖中有shuffle操作。

所以,发生了shuffle操作的就是宽依赖。


识别方法

RDD阶段划分

为什么需要划分阶段呢?


为什么?

我们先了解一下fork/join机制。

fork单词含义是叉子,他的操作过程也和叉子一样,一个RDD转换成一个新的RDD出来,里面的分区也会转换成相对应的分区。


fork机制

这样出来的效果就好像一把叉子的几个叉,里面分区的转换是并行执行,也就是窄依赖。

在所有的转换操作结束后,我们就需要把所有的RDD汇总起来,这时就不是并行执行而是交叉执行了。

示意图

我们可以看这张图,join过程是多个分区合并成了一个分区,发生了shuffle操作,所以这个过程是宽依赖。

我们来举一个实例:
现在我们有两个班要从北京前往厦门,因为人数众多,分成了男女两队前往,其中男生由班长带头前往,女生由组织委员带领,他们从北京飞到上海中转,在这个过程中,在飞机上的过程是fork,在上海机场汇合的过程是join。

示意图

按照正常情况,我们从北京飞到厦门一共花了5个小时,但是在spark的世界中,我们花了6个小时。因为他们必须在上海和厦门同时完成集结。
这样是可以进行一次优化的,我们没必要非要在上海集结一次。


优化

我们可以把上海集结看做是存磁盘的操作,我们没必要进行这一下。

第一种运输方式就是窄依赖,虽然发生了暂存,但是分区没有发生变化(依旧是男生一组,女生一组),这样就可以进行优化。


窄依赖

而什么时候必须要进行暂存呢,就是下面这种情况,到达上海后,两个班不在分男女,而是按照班级编制飞往厦门,这时的分区发生了改变,就必须暂存一下。


宽依赖
反向解析

你可能感兴趣的:(1.5.1.1 Spark-RDD)