Spark简介
MapReduce 的缺陷
MapReduce 通过简单的 Map 和 Reduce 的抽象提供了一个编程模型,可以在一个由上百台机器组成的集群上并发处理大量的数据集,而把计算细节隐藏起来。各种各样的复杂数据处理都可以分解为 Map 或 Reduce 的基本元素。
这样,复杂的数据处理可以分解为由多个 Job(包含一个 Mapper 和一个 Reducer)组成的有向无环图(DAG),然后每个 Mapper 和 Reducer 放到 Hadoop 集群上执行,就可以得出结果。
我们在第一讲中讲到过 MapReduce 被硅谷一线公司淘汰的两大主要原因:高昂的维护成本、时间性能“达不到”用户的期待。不过除此之外,MapReduce 还存在诸多局限。
第一,MapReduce 模型的抽象层次低,大量的底层逻辑都需要开发者手工完成。
打个比方,写 MapReduce 的应用就好比用汇编语言去编写一个复杂的游戏。如果你是开发者,你会习惯用汇编语言,还是使用各种高级语言如 Java、C++ 的现有框架呢?
第二,只提供 Map 和 Reduce 两个操作。
很多现实的数据处理场景并不适合用这个模型来描述。实现复杂的操作很有技巧性,也会让整个工程变得庞大以及难以维护。
举个例子,两个数据集的 Join 是很基本而且常用的功能,但是在 MapReduce 的世界中,需要对这两个数据集做一次 Map 和 Reduce 才能得到结果。这样框架对于开发者非常不友好。正如第一讲中提到的,维护一个多任务协调的状态机成本很高,而且可扩展性非常差。
第三,在 Hadoop 中,每一个 Job 的计算结果都会存储在 HDFS 文件存储系统中,所以每一步计算都要进行硬盘的读取和写入,大大增加了系统的延迟。
由于这一原因,MapReduce 对于迭代算法的处理性能很差,而且很耗资源。因为迭代的每一步都要对 HDFS 进行读写,所以每一步都需要差不多的等待时间。
第四,只支持批数据处理,欠缺对流数据处理的支持。
因此,在 Hadoop 推出后,有很多人想办法对 Hadoop 进行优化,其中发展到现在最成熟的就是 Spark。
接下来,就让我们看一下 Spark 是如何对上述问题进行优化的。
Spark 的优势
Spark 最基本的数据抽象叫作弹性分布式数据集(Resilient Distributed Dataset, RDD),它代表一个可以被分区(partition)的只读数据集,它内部可以有很多分区,每个分区又有大量的数据记录(record)。
RDD 是 Spark 最基本的数据结构。Spark 定义了很多对 RDD 的操作。对 RDD 的任何操作都可以像函数式编程中操作内存中的集合一样直观、简便,使得实现数据处理的代码非常简短高效。这些我们会在这一模块中的后续文章中仔细阐述。
Spark 提供了很多对 RDD 的操作,如 Map、Filter、flatMap、groupByKey 和 Union 等等,极大地提升了对各种复杂场景的支持。开发者既不用再绞尽脑汁挖掘 MapReduce 模型的潜力,也不用维护复杂的 MapReduce 状态机。
相对于 Hadoop 的 MapReduce 会将中间数据存放到硬盘中,Spark 会把中间数据缓存在内存中,从而减少了很多由于硬盘读写而导致的延迟,大大加快了处理速度。
Databricks 团队曾经做过一个实验,他们用 Spark 排序一个 100TB 的静态数据集仅仅用时 23 分钟。而之前用 Hadoop 做到的最快记录也用了高达 72 分钟。此外,Spark 还只用了 Hadoop 所用的计算资源的 1/10,耗时只有 Hadoop 的 1/3。
这个例子充分体现出 Spark 数据处理的最大优势——速度。
在某些需要交互式查询内存数据的场景中,Spark 的性能优势更加明显。
根据 Databricks 团队的结果显示,Spark 的处理速度是 Hadoop 的 100 倍。即使是对硬盘上的数据进行处理,Spark 的性能也达到了 Hadoop 的 10 倍。
由于 Spark 可以把迭代过程中每一步的计算结果都缓存在内存中,所以非常适用于各类迭代算法。
Spark 第一次启动时需要把数据载入到内存,之后的迭代可以直接在内存里利用中间结果做不落地的运算。所以,后期的迭代速度快到可以忽略不计。在当今机器学习和人工智能大热的环境下,Spark 无疑是更好的数据处理引擎。
下图是在 Spark 和 Hadoop 上运行逻辑回归算法的运行时间对比。
image.png可以看出,Hadoop 做每一次迭代运算的时间基本相同,而 Spark 除了第一次载入数据到内存以外,别的迭代时间基本可以忽略。
在任务(task)级别上,Spark 的并行机制是多线程模型,而 MapReduce 是多进程模型。
多进程模型便于细粒度控制每个任务占用的资源,但会消耗较多的启动时间。
而 Spark 同一节点上的任务以多线程的方式运行在一个 JVM 进程中,可以带来更快的启动速度、更高的 CPU 利用率,以及更好的内存共享。
从前文中你可以看出,Spark 作为新的分布式数据处理引擎,对 MapReduce 进行了很多改进,使得性能大大提升,并且更加适用于新时代的数据处理场景。
image.pngSpark 有五个主要的扩展库,分别是支持结构化数据的 Spark SQL、处理实时数据的 Spark Streaming、用于机器学习的 MLlib、用于图计算的 GraphX、用于统计分析的 SparkR。