本节书摘来自华章出版社《Spark大数据分析:核心概念、技术及实践》一书中的第3章,第3.1节,作者[美] 穆罕默德·古勒(Mohammed Guller),更多章节内容可以访问云栖社区“华章计算机”公众号查看。
第3章
Spark Core
Spark是大数据领域最活跃的开源项目,甚至比Hadoop还要热门。如第1章所述,它被认为是Hadoop的继任者。Spark的使用率大幅增长。很多组织正在用Spark取代Hadoop。
从概念上看,Spark类似于Hadoop,它们都用于处理大数据。它们都能用商用硬件以很低的成本处理大数据。然而,相比于Hadoop,Spark有很多的优势,这些将在本章进行介绍。
本章主要介绍Spark Core,这也是Spark生态系统的基础。我们首先概述Spark Core,然后介绍Spark的总体架构和应用程序运行时的情况。Spark Core的编程接口也会一并介绍。
3.1 概述
Spark是一个基于内存的用于处理、分析大数据的集群计算框架。它提供了一套简单的编程接口,从而使得应用程序开发者方便使用集群节点的CPU、内存、存储资源来处理大数据。
3.1.1 主要特点
Spark的主要特点如下:
使用方便
快速
通用
可扩展
容错
使用方便
Spark提供了比MapReduce更简单的编程模型。使用Spark开发分布式的数据处理应用程序比用MapReduce简单多了。
Spark针对开发大数据应用程序提供了丰富的API。它提供了80多个用于处理数据的操作符。而且,Spark提供了比Hadoop MapReduce更易读的API。相比之下,Hadoop MapReduce只有两个操作符,map和reduce。Hadoop要求任何问题都必须能够分解为一系列的map作业和reduce作业。然而,有些算法却难以只用map和reduce来描述。相比于Hadoop MapReduce,使用Spark提供的操作符来处理复杂的数据显得更加简单。
而且,使用Spark可以写出比用Hadoop MapReduce更简洁的代码。用Hadoop Map-Reduce需要写大量的模块代码。同样的数据处理算法,用Hadoop MapReduce实现需要50行,而用Spark只需要10不到。有了丰富易读的API,消除了模块代码,开发者的生产力大幅提升。相对于使用Hadoop,使用Spark开发者的生产力会有5~10倍的提升。
快速
Spark要比Hadoop快上若干个数量级。如果数据都加载在内存中,它能快上数百倍,哪怕数据无法完全载入内存,Spark也能快上数十倍。
尤其是在处理大数据集的时候,速度显得至关重要。如果一个处理数据的作业要花费数天或小时,那么它将拖慢决策的速度,从而降低数据的价值。反之,如果同样的处理能提速十倍乃至百倍,它将会创造更多的机会。它甚至可能开创出前所未有的新数据驱动应用程序。
Spark比Hadoop快的原因有两方面。一方面,它可以使用基于内存的集群计算。另一方面,它实现了更先进的执行引擎。
得益于基于内存的集群计算,Spark的性能有了数量级的提升。相比于从硬盘读取数据,采用从内存读取数据的方式,获得的顺序读取吞吐量要大100倍。换句话说,从内存读取数据要比从硬盘快100倍。当应用程序只读取和处理少量数据时,内存和硬盘之间读取速度的差距并不太明显。然而,一旦数据量达到太字节级别,I/O延迟(数据从硬盘载入内存所花费的时间)就会显著影响作业执行时间。
Spark允许应用程序利用内存缓存数据。这能减少磁盘I/O。一个基于MapReduce的数据处理流水线可能包含多个作业。每个作业都需要从硬盘载入数据,处理它,而后再写入硬盘中。而且,一个使用MapReduce实现的复杂数据处理应用程序可能需要反复从硬盘读取数据,写入数据。由于Spark允许利用内存缓存数据,因此使用Spark实现的同样的应用程序只需要从硬盘读取数据一次即可。一旦数据缓存在内存中,接下来的每一个操作都可以直接操作缓存的数据。就像前面说的一样,Spark可以减少I/O延迟,这样就能显著减少作业总的执行时间。
需要注意的是,Spark不会自动将输入数据缓存在内存中。一个普遍的误解是,一旦无法把输入数据完全载入内存,那么Spark将无法使用。这并不正确。Spark可以在集群上处理太字节级的数据,哪怕集群的总内存只有仅仅100GB。在数据处理流水线上何时缓存和缓存哪部分数据完全由应用程序决定。实际上,如果数据处理应用程序只使用一次数据,那么它完全不需要缓存数据。
Spark比Hadoop MapReduce快的第二个原因是它拥有更先进的作业执行引擎。Spark和Hadoop一样都将一个作业转化为由若干个阶段构成的有向无环图(DAG)。如果你不熟悉图论,这里简单介绍下。图是一个由顶点构成的集合,这些顶点由边相连。有向图指的是那些边有方向的图。无环图指的是不存在环路的图。DAG指的就是不存在环路的有向图。换句话说,在DAG中不存在一条起点和终点都是同一个顶点的通路。第11章将对图进行更详细的介绍。
Hadoop MapReduce对任意一个作业都会创建由map和Reduce两个阶段构成的有向无环图。如果一个复杂的数据处理算法用MapReduce实现,可能需要划分成多个作业,而后按顺序执行。这种设计导致Hadoop MapReduce无法做任何的优化。
与之相反,Spark并没有迫使开发者在实现数据处理算法的时候将其划分成多个作业。Spark中的DAG可以包含任意个阶段。一个简单的作业可能只有一个阶段,而一个复杂的作业可能会有多个阶段。这使得Spark可以做些Hadoop无法实现的优化。Spark可以一次执行一个包含多阶段的复杂作业。因为它拥有所有阶段的信息,所以可以进行优化。举例来说,它可以减少磁盘I/O和数据shuffle操作的时间。数据的shuffle操作通常会涉及网络间的数据传输,并且会增加应用程序的执行时间。
通用
Spark为各种类型的数据处理作业提供一个统一的集成平台。它可以用于批处理、交互分析、流处理、机器学习和图计算。相比之比,Hadoop MapReduce只适合批处理。因此一个使用Hadoop MapReduce的开发者为了能做流处理和图计算只能使用其他的框架。
对于不同类型的数据处理作业使用不同的框架,带来了很多问题。首先,开发者不得不学习各种框架,每种框架的接口都不相同。这降低了开发者的生产力。其次,每种框架都相对独立。因此,数据也必须复制多份,存放在不同的地方。类似地,代码也必须重复多份,存放在多个地方。比如,你想使用Hadoop MapReduce处理历史数据,同时使用Storm(一个流处理框架)处理流式数据,二者采用同样的算法,那么你不得不维护两份相同的代码,一份是Hadoop MapReduce的,一份是Storm的。最后,同时使用多个框架带来了运维上的麻烦。你得为每一个框架创建并维护一个单独的集群。要知道维护多个集群可比维护一个困难多了。
Spark自带了一系列的库,用于批处理、交互分析、流处理、机器学习和图计算。使用Spark,可以使用单一框架来创建一个包含多个不同类型任务的数据处理流水线。从而,再也没有必要为了多个不同类型的数据处理任务而学习不同框架或者部署单独的集群了。使用Spark有助于降低运维的困难度,减少代码和数据的重复。
有意思的是,越来越多流行的应用和库开始集成到Spark中或添加了对Spark的支持,而它们一开始是使用Hadoop作为其执行引擎的。比如Apache Mahout(一个构建于Hadoop之上的机器学习库)正在集成到Spark中。到了2014年4月,Mahout的开发者已经放弃了Hadoop并且不再添加新的基于MapReduce的机器学习算法了。
同样地,Hive(见第1章)的开发者也正在开发一个运行在Spark上的版本。Pig(一个可以用脚本语言来创建数据处理流水线的数据分析平台)同样支持Spark作为它的执行引擎。Cascading(一个用于开发Hadoop数据应用程序的应用开发平台)也添加了对Spark的支持。
可拓展
Spark是可扩展的。Spark集群的数据处理能力可以通过增加更多集群节点的方式得以提升。你可以从一个小集群开始,随着数据量的增加,逐渐增加更多的计算能力。这相当经济。
而且,Spark的这个特性对于应用程序来说是透明的。当你往Spark集群增加节点的时候无须改动任何代码。
容错
Spark是可容错的。一个由数百个节点构成的集群中,每个节点在任何一天故障的可能性都很高。硬盘损坏或其他硬件问题都有可能导致节点不可用。Spark能自动处理集群中的节点故障。一个节点故障可能会导致性能下降但不会导致应用无法运行。
既然Spark能自动处理节点故障,应用程序的开发者就不必在应用中处理这样的异常情况了,这简化了应用程序的代码。
3.1.2 理想的应用程序
就像前面讨论的那样,Spark是一个通用框架,它用于各种大数据应用中。然而,对于一个理想的大数据应用程序而言,速度是相当重要的。使用迭代数据处理算法的应用和交互分析都是这样的典型应用。
迭代算法
迭代算法是指那些在同样数据上迭代多次的数据处理算法。使用这类算法的应用包括机器学习和图处理应用。这些应用都在同样的数据上迭代数十次乃至数百次算法。对于这类应用,Spark是理想的选择。
Spark内存计算的特性使得在Spark上面执行这些迭代算法比较快。由于Spark允许应用在内存中缓存数据,因此一个迭代算法哪怕需要迭代100次,也只需要在第一次迭代的时候从硬盘读取数据,接下来的迭代都从内存中读取。而从内存中读取数据比从硬盘要快100倍,所以在Spark上运行这些应用能快上一个数量级。
交互分析
交互式数据分析涉及交互式地探索数据。举例来说,对于一个巨型数据集,在触发一个可能需要花费数小时的长时间运行的批处理作业之前,先进行汇总分析是很有用的。类似地,一个商业分析师可能想要使用BI或数据可视化工具来进行交互分析。在这种场景下,用户会在同一个数据集上执行多个查询。Spark就提供了这样一个用于大数据交互分析的理想平台。
Spark适用于交互分析的理由还是它的内存计算特性。应用程序可以缓存数据,从而使得数据能够在内存中进行交互分析。第一个查询请求从硬盘读取数据,但是接下来的一连串请求都从内存中读取缓存数据。查询内存中的数据要比硬盘中的数据快上一个数量级。当数据缓存在内存中的时候,一个查询请求可能只需要花费数秒,而在硬盘中则需要不止一个小时。