3.1 RDD是什么
RDD是Resilient Distributed Datasets的简称,翻译成中文为“弹性分布式数据集”,这个语义揭示了RDD实质上是存储在不同节点计算机中的数据集。分布式存储最大的好处是可以让数据在不同的工作节点上并行存储,以便在需要数据的时候并行运算,从而获得最迅捷的运行效率。
3.1.1 RDD名称的秘密
Resilient是弹性的意思。在Spark中,弹性指的是数据的存储方式,即数据在节点中进行存储时候,既可以使用内存也可以使用磁盘。这为使用者提供了很大的自由,提供了不同的持久化和运行方法,有关这点,我们会在后面详细介绍。
除此之外,弹性还有一个意思,即RDD具有很强的容错性。这里容错性指的是Spark在运行计算的过程中,不会因为某个节点错误而使得整个任务失败。不同节点中并发运行的数据,如果在某一个节点发生错误时,RDD会自动将其在不同的节点中重试。关于RDD的容错性,这里尽量避免理论化探讨,尽量讲解得深入一些,毕竟这本书是以实战为主。
关于分布式数据的容错性处理是涉及面较广的问题,较为常用的方法主要是两种:
● 检查节点
● 更新记录
检查节点的方法是对每个数据节点逐个进行检测,随时查询每个节点的运行情况。这样做的好处是便于操作主节点随时了解任务的真实数据运行情况,而坏处在于由于系统进行的是分布式存储和运算,节点检测的资源耗费非常大,而且一旦出现问题,需要将数据在不同节点中搬运,反而更加耗费时间从而极大地拉低了执行效率。
更新记录指的是运行的主节点并不总是查询每个分节点的运行状态,而是将相同的数据在不同的节点(一般情况下是3个)中进行保存,各个工作节点按固定的周期更新在主节点中运行的记录,如果在一定时间内主节点查询到数据的更新状态超时或者有异常,则在存储相同数据的不同节点上重新启动数据计算工作。其缺点在于如果数据量过大,更新数据和重新启动运行任务的资源耗费也相当大。
3.1.2 RDD特性
前面已经介绍,RDD是一种分布式弹性数据集,将数据分布存储在不同节点的计算机内存中进行存储和处理。每次RDD对数据处理的最终结果,都分布存放在不同的节点中。这样的话,在进行到下一步数据处理工作时,数据可以直接从内存中提取,从而省去了大量的IO操作,这对于传统的MapReduce操作来说,更便于使用迭代运算提升效率。
RDD的另外一大特性是延迟计算,即一个完整的RDD运行任务被分成两部分:Transformation和Action。
1. Transformation
Transformation用于对RDD的创建。在Spark中,RDD只能使用Transformation来创建,同时Transformation还提供了大量的操作方法,例如map、filter、groupBy、join等操作来对RDD进行处理。除此之外,RDD可以利用Transformation来生成新的RDD,这样可以在有限的内存空间中生成尽可能多的数据对象。但是有一点请读者牢记,无论发生了多少次Transformation,在RDD中真正数据计算运行的操作Action都不可能真正运行。
2. Action
Action是数据的执行部分,其通过执行count、reduce、collect等方法去真正执行数据的计算部分。实际上,RDD中所有的操作都是使用的Lazy模式进行,Lazy是一种程序优化的特殊形式。运行在编译的过程中不会立刻得到计算的最终结果,而是记住所有的操作步骤和方法,只有显式地遇到启动命令才进行计算。
这样做的好处在于大部分的优化和前期工作在Transformation中已经执行完毕,当Action进行工作时,只需要利用全部自由完成业务的核心工作。读者可以参照图3-1加以体会。
图3-1 RDD核心流程
3.1.3 与其他分布式共享内存的区别
可能有读者在以前的学习或工作中了解到,分布式共享内存(Distributed Shared Memory,简称DSM)系统是一种较为常用的分布式框架。在架构完成的DSM系统中,用户可以向框架内节点的任意位置进行读写操作。这样做有非常大的便捷性,可以使得数据脱离本地单节点束缚,但是在进行大规模计算时,对容错性容忍程度不够,常常因为一个节点产生错误而使得整个任务失败。
RDD与一般DSM有很大的区别,首先RDD在框架内限制了批量读写数据的操作,有利于整体的容错性提高。此外,RDD并不单独等待某个节点任务完成,而是使用“更新记录”的方式去主动性维护任务的运行,在某一个节点中任务失败,而只需要在存储数据的不同节点上重新运行即可。
提示
建议读者将RDD与DSM异同点列出做个对比查阅。因为不是本章重点,请读者自行完成。
3.1.4 RDD缺陷
在前面已经说过,RDD相对于一般的DSM,更加注重与批量数据的读写,并且将优化和执行进行分类。通过Transformation生成多个RDD,当其在执行Action时,主节点通过“记录查询”的方式去确保任务的政策执行。
但是由于这些原因,使得RDD并不适合作为一个数据的存储和抓取框架,因为RDD主要执行在多个节点中的批量操作,即一个简单的写操作也会分成两个步骤进行,这样反而会降低运行效率。例如一般网站中的日志文件存储,更加适合使用一些传统的MySQL数据库进行存储,而不适合采用RDD。