深入浅出Spark(二) 什么是RDD


(xmnz) #1

本系列讲座是沁原对Sameer Farooqui的《Advanced Apache Spark》的解说。

完整视频:https://www.bittiger.io/videos/NBATgDTurWQmEqNQ6/HbcfjrPGxJHvKyzQR?utm_source=zhihu&utm_medium=zhihuAirticle&utm_content=Article817Post&utm_campaign=zhihu

原始视频参考https://www.youtube.com/watch?v=7ooZ4S7Ay6Y

(二)什么是RDD?

1. RDD的官方定义

RDD是Spark中的数据抽象,意思是弹性分布式数据集。在逻辑上是一个数据集,在物理上则可以分块分布在不同的机器上并发运行。RDD的数据具有不可变性(immutable)

![](data:image/svg+xml;utf8,)

图.1. 一个逻辑RDD在物理上分块存储在不同的服务器。

如图所示,一个RDD数据集被分成了五块,运行在了三个worker服务器上。第一台上运行了两个RDD数据块,第二台上运行两个RDD数据库块,第三台上运行剩下的一个数据块。

2. RDD的生命周期

在Spark程序中,首先要读取或创建RDD, 然后对数据进行一系列的变换操作(Transform),保存中间结果(Cache),最后对变换结果进行处理(Action)

2.1 RDD的产生可以通过对内存中的数据并行化,或直接读取分布式数据库(S3, HDFS, Cassandra 等等)而来。

![](data:image/svg+xml;utf8,)

图.2. 通过parallelize接口,将内存数据变成RDD。(图中sc指的是spark context实例。)

![](data:image/svg+xml;utf8,)

图.3. 直接读取文件生成RDD.

2.2. RDD支持数据变换接口,如常用的filter, map等等,在变换的过程中,RDD的数据并不立即发生实际变化(Lazily transform),而是保存了数据的依赖关系,直到要求RDD进行动作(Action)时。RDD会从全局的角度来优化Transform的运行过程。从而节省时间。

2.3 RDD的cache操作将数据的中间结果保存在内存中,方便下次使用。

2.4 RDD的Action操作将数据的运算结果进行统计和返回。常见的如count 和 collect.

![](data:image/svg+xml;utf8,)

图.4. RDD操作实例

举个例子。如图4所示。从日志(Log)数据库中读取的文件生成logLinesRDD, 形成了四个物理分块。通过filter变换提取出日志中的错误信息, 形成errorsRDD。 通过合并coalesce形成两个块。进一步过滤提取只包含错误1的日志errorMsg1RDD。最后进行collect 动作, 将结果合并返回到Driver。中间结果,我们使用了count动作来返回一共有多少条错误日志 。用saveToCassandra将错误日志保存到Cassandra数据库中。图中绿色的箭头表示Action。红色箭头表示Transformation。

3. 根据数据源,RDD可以分成许多类,比如从Jdbc得来的RDD是JdbcRDD.

![](data:image/svg+xml;utf8,)

图.5. RDD分类

每一类的RDD都定义如下几个重要的的特征。

  1. 如何分块。(Partition)

  2. 与父RDD的依赖关系(Dependency)

  3. 从父RDD求子RDD的函数(function)

  4. 希望当前RDD存储的位置(preferred location)

  5. 负责存储RDD的分块类(Partitioner)

特征2,3是保存了数据的产生方式, 当数据丢失时可以进行数据恢复。4,5是本地化存储策略。通过尽可能的本地存储来提高运算速度。

![](data:image/svg+xml;utf8,)

例一: HadoopRDD

通过读HDFS生成的RDD。它的分块策略是每个HDFS块生成一个分块。该RDD没有父节点。我们希望这个RDD的数据块存在HDFS数据块相同的位置。不用进一步分块。

![](data:image/svg+xml;utf8,)

![](data:image/svg+xml;utf8,)

![](data:image/svg+xml;utf8,)

例二. FilteredRDD

FilteredRDD产生在Filter操作后。分块与父RDD相同。与父RDD一一对应, 存储位置与父块相同。

![](data:image/svg+xml;utf8,)

![](data:image/svg+xml;utf8,)

例三:JoinedRDD

该RDD产生在shuffle操作之后。每个reduce操作有一个分区。依赖于被shuffle的父RDD。进一步分区是通过HashPartitioner实现的。

4. 总结

本节讲解了

  1. 什么是RDD

  2. RDD的生命周期。 创建(Create),懒变换(Lazily Transform),缓存(Cache),和动作(Action)。

  3. RDD的分类和特征。

本文作者Lion, 更多精彩内容,欢迎访问官网 http://BitTiger.io 或关注 “论码农的自我修养” 微信公众号:bit_tiger