1. 什么是Spark?Spark作为Apache顶级的开源项目,是一个快速、通用的大规模数据处理引擎,和Hadoop的MapReduce计算框架类似,但是相对于MapReduce,Spark凭借其可伸缩、基于内存计算等特点,以及可以直接读写Hadoop上任何格式数据的优势,进行批处理时更加高效,并有更低的延迟。相对于“one stack to rule them all”的目标,实际上,Spark已经成为轻量级大数据快速处理的统一平台,各种不同的应用,如实时流处理、机器学习、交互式查询等,都可以通过Spark建立在不同的存储和运行系统上。
2. Spark是基于内存计算的大数据并行计算框架。Spark基于内存计算,提高了在大数据环境下数据处理的实时性,同时保证了高容错性和高可伸缩性,允许用户将Spark部署在大量廉价硬件之上,形成集群。
3. Spark于2009年诞生于加州大学伯克利分校AMPLab。目前,已经成为Apache软件基金会旗下的顶级开源项目。相对于MapReduce上的批量计算、迭代型计算以及基于Hive的SQL查询,Spark可以带来上百倍的性能提升。目前Spark的生态系统日趋完善,Spark SQL的发布、Hive on Spark项目的启动以及大量大数据公司对Spark全栈的支持,让Spark的数据分析范式更加丰富。
伯克利数据分析栈(DBAS)图:
相较于国内外较多的大数据处理框架,Spark以其低延时的出色表现,正在成为继Hadoop的MapReduce之后,新的、最具影响的大数据框架之一。以Spark为核心的整个生态圈,最底层为分布式存储系统HDFS、Amazon S3、Mesos,或者其他格式的存储系统(如HBase);资源管理采用Mesos、YARN等集群资源管理模式,或者Spark自带的独立运行模式,以及本地运行模式。在Spark大数据处理框架中,Spark为上层多种应用提供服务。例如,Spark SQL提供SQL查询服务,性能比Hive快3~50倍;MLlib提供机器学习服务;GraphX提供图计算服务;Spark Streaming将流式计算分解成一系列短小的批处理计算,并且提供高可靠和吞吐量服务。值得说明的是,无论是Spark SQL、Spark Streaming、GraphX还是MLlib,都可以使用Spark核心API处理问题,它们的方法几乎是通用的,处理的数据也可以共享,不仅减少了学习成本,而且其数据无缝集成大大提高了灵活性。
框架中核心组件图:
更准确地说,Spark是一个计算框架,而Hadoop中包含计算框架MapReduce和分布式文件系统HDFS,Hadoop更广泛地说还包括在其生态系统上的其他系统,如Hbase、Hive等。Spark是MapReduce的替代方案,而且兼容HDFS、Hive等分布式存储层,可融入Hadoop的生态系统,以弥补缺失MapReduce的不足。
Spark与Hadoop在数据中间数据处理区别:
Spark相比Hadoop MapReduce的优势如下。
基于MapReduce的计算引擎通常会将中间结果输出到磁盘上,进行存储和容错。出于任务管道承接的考虑,当一些查询翻译到MapReduce任务时,往往会产生多个Stage,而这些串联的Stage又依赖于底层文件系统(如HDFS)来存储每一个Stage的输出结果。
Spark将执行模型抽象为通用的有向无环图执行计划(DAG),这可以将多Stage的任务串联或者并行执行,而无须将Stage中间结果输出到HDFS中。类似的引擎包括Dryad、
Tez。
由于MapReduce Schema on Read处理方式会引起较大的处理开销。Spark抽象出分布式内存存储结构弹性分布式数据集RDD,进行数据的存储。RDD能支持粗粒度写操作,但对于读取操作,RDD可以精确到每条记录,这使得RDD可以用来作为分布式索引。Spark的特性是能够控制数据在不同节点上的分区,用户可以自定义分区策略,如Hash分区等。Shark和Spark SQL在Spark的基础之上实现了列存储和列存储压缩。
MapReduce在数据Shuffle之前花费了大量的时间来排序,Spark则可减轻上述问题带来的开销。因为Spark任务在Shuffle中不是所有情景都需要排序,所以支持基于Hash的分布式聚合,调度中采用更为通用的任务执行计划图(DAG),每一轮次的输出结果在内存缓存。
传统的MapReduce系统,如Hadoop,是为了运行长达数小时的批量作业而设计的,在某些极端情况下,提交一个任务的延迟非常高。Spark采用了事件驱动的类库AKKA来启动任务,通过线程池复用线程来避免进程或线程启动和切换开销。
基于Hadoop的资源管理器YARN实际上是一个弹性计算平台,作为统一的计算资源管理框架,不仅仅服务于MapReduce计算框架,而且已经实现了多种计算框架进行统一管理。这种共享集群资源的模式带来了很多好处。
1. 快速
Spark有先进的DAG执行引擎,支持循环数据流和内存计算;Spark程序在内存中的运行速度是Hadoop MapReduce运行速度的100倍,在磁盘上的运行速度是Hadoop MapReduce运行速度的10倍。
2. 易用
Spark支持使用Java、Scala、Python语言快速编写应用,提供超过80个高级运算符,使得编写并行应用程序变得容易。
3. 通用
Spark可以与SQL、Streaming以及复杂的分析良好结合。基于Spark,有一系列高级工具,包括Spark SQL、MLlib(机器学习库)、GraphX和Spark Streaming,支持在一个应用中同时使用这些架构。
4. 有效集成Hadoop
Spark可以指定Hadoop,YARN的版本来编译出合适的发行版本,Spark也能够很容易地运行在EC2、Mesos上,或以Standalone模式运行,并从HDFS、HBase、Cassandra和其他Hadoop数据源读取数据。
5.资源利用率高
多种框架共享资源的模式有效解决了由于应用程序数量的不均衡性导致的高峰时段任务比较拥挤,空闲时段任务比较空闲的问题;同时均衡了内存和CPU等资源的利用。
6.实现了数据共享
随着数据量的增加,数据移动成本越来越高,网络带宽、磁盘空间、磁盘IO都会成为瓶颈,在分散数据的情况下,会造成任务执行的成本提高,获得结果的周期变长,而数据共享模式可以让多种框架共享数据和硬件资源,大幅度减少数据分散带来的成本。
7.有效降低运维和管理成本
相比较一种计算框架需要一批维护人员,而运维人员较多又会带来的管理成本的上升;共享模式只需要少数的运维人员和管理人员即可完成多个框架的统一运维管理,便于运维优化和运维管理策略统一执行。
总之,Spark凭借其良好的伸缩性、快速的在线处理速度、具有Hadoop基因等一系列优势,迅速成为大数据处理领域的佼佼者。
Spark的一站式解决方案有很多的优势,具体如下。
Spark支持复杂查询。在简单的“map”及“reduce”操作之外,Spark还支持SQL查询、流式计算、机器学习和图算法。同时,用户可以在同一个工作流中无缝搭配这些计算范式。
Spark 1.0核心代码只有4万行。这是由于Scala语言的简洁和丰富的表达力,以及Spark充分利用和集成Hadoop等其他第三方组件,同时着眼于大数据处理,数据处理速度是至关重要的,Spark通过将中间结果缓存在内存减少磁盘I/O来达到性能的提升。
3. 易于使用,Spark支持多语言
Spark支持通过Scala、Java及Python编写程序,这允许开发者在自己熟悉的语言环境下进行工作。它自带了80多个算子,同时允许在Shell中进行交互式计算。用户可以利用Spark像书写单机程序一样书写分布式程序,轻松利用Spark搭建大数据内存计算平台并充分利用内存计算,实现海量数据的实时处理。
Spark可以独立运行,除了可以运行在当下的YARN等集群管理系统之外,它还可以读取已有的任何Hadoop数据。这是个非常大的优势,它可以运行在任何Hadoop数据源上,如Hive、HBase
Spark架构采用了分布式计算中的Master-Slave模型。Master是对应集群中的含有Master进程的节点,Slave是集群中含有Worker进程的节点。Master作为整个集群的控制器,负责整个集群的正常运行;Worker相当于是计算节点,接收主节点命令与进行状态汇报;Executor负责任务的执行;Client作为用户的客户端负责提交应用,Driver负责控制一个应用的执行,如图1-4所示:
Spark集群部署后,需要在主节点和从节点分别启动Master进程和Worker进程,对整个集群进行控制。在一个Spark应用的执行过程中,Driver和Worker是两个重要角色。Driver程序是应用逻辑执行的起点,负责作业的调度,即Task任务的分发,而多个Worker用来管理计算节点和创建Executor并行处理任务。在执行阶段,Driver会将Task和Task所依赖的file和jar序列化后传递给对应的Worker机器,同时Executor对相应数据分区的任务进行处理。
下面详细介绍Spark的架构中的基本组件。
Spark的整体流程为:Client提交应用,Master找到一个Worker启动Driver,Driver向Master或者资源管理器申请资源,之后将应用转化为RDD Graph,再由DAGScheduler将RDD Graph转化为Stage的有向无环图提交给TaskScheduler,由TaskScheduler提交任务给Executor执行。在任务执行的过程中,其他组件协同工作,确保整个应用顺利执行。
如图1-5所示,在Spark应用中,整个执行流程在逻辑上会形成有向无环图(DAG)。
Action算子触发之后,将所有累积的算子形成一个有向无环图,然后由调度器调度该图上的任务进行运算。Spark的调度方式与MapReduce有所不同。Spark根据RDD之间不同的依赖关系切分形成不同的阶段(Stage),一个阶段包含一系列函数执行流水线。图中的A、B、C、D、E、F分别代表不同的RDD,RDD内的方框代表分区。数据从HDFS输入Spark,形成RDD A和RDD C,RDD C上执行map操作,转换为RDD D,RDD B和RDD E执行join操作,转换为F,而在B和E连接转化为F的过程中又会执行Shuffle,最后RDD F通过函数saveAsSequenceFile输出并保存到HDFS中。
我们通常所说的分布式系统主要指的是分布式软件系统,它是在通信网络互连的多处理机的架构上执行任务的软件系统,包括分布式操作系统、分布式程序设计语言、分布式文件系统和分布式数据库系统等。Spark是分布式软件系统中的分布式计算框架,基于Spark可以编写分布式计算程序和软件。为了整体宏观把握和理解分布式系统,可以将一个集群视为一台计算机。分布式计算框架的最终目的是方便用户编程,最后达到像原来编写单机程序一样编写分布式程序。但是分布式编程与编写单机程序还是存在不同点的。由于分布式架构和单机的架构有所不同,存在内存和磁盘的共享问题,这也是我们在书写和优化程序的过程中需要注意的地方。分布式架构与单机架构的对比如图1-6所示
1)在单机多核环境下,多CPU共享内存和磁盘。当系统所需的计算和存储资源不够,需要扩展CPU和存储时,单机多核系统显得力不从心。
2)大规模分布式并行处理系统是由许多松耦合的处理单元组成的,要注意的是,这里
指的是处理单元而非处理器。每个单元内的CPU都有自己私有的资源,如总线、内存、硬盘等。这种结构最大的特点在于不共享资源。在不共享资源(Share Nothing)的分布式架构下,节点可以实现无限扩展,即计算能力和存储的扩展性可以成倍增长。
在分布式运算下,数据尽量本地运算,减少网络I/O开销。由于大规模分布式系统要在
不同处理单元之间传送信息,在网络传输少时,系统可以充分发挥资源的优势,达到高效
率。也就是说,如果操作相互之间没有什么关系,处理单元之间需要进行的通信比较少,则
采用分布式系统更好。因此,分布式系统在决策支持(DSS)和数据挖掘(Data Mining)方面具有优势。
Spark正是基于大规模分布式并行架构开发,因此能够按需进行计算能力与存储能力的
扩展,在应对大数据挑战时显得游刃有余,同时保证容错性,让用户放心地进行大数据分
析。
大家知道,在Hadoop中完成即席查询(ad-hoc queries)、批处理(batch processing),流式处理(stream processing),需要构建不同的团队,每个团队需要不同的技术和经验,很难做到共享。而Spark实现了平台融合,一个基础平台解决所有的问题,一个团队拥有相同的技术和经验完成所有的任务。 基于Spark的基础平台扩展了5个主要的Spark库,包括支持结构化数据的Spark SQL、处理实时数据的Spark Streaming、用于机器学习的MLlib、用于图计算的GraphX、用于统计分析的SparkR,各种程序库与Spark核心API高度整合在一起,并在持续不断改进。
Spark的一个处理结构化数据的模块,提供一个DataFrame编程抽象。它可以看作是一个分布式SQL查询引擎,主要由Catalyst优化、Spark SQL内核、Hive支持三部分组成。 相对于传统的MapReduce API,Spark的RDD API有了数量级的飞跃,从Spark SQL 1.3.0开始,在原有SchemaRDD的基础上提供了与R风格类似的DataFrame API。 DataFrame是以指定列(named columns)组织的分布式数据集合,在Spark SQL中,相当于关系数据库的一个表,或R/Python的一个数据框架,但后台更加优化。 DataFrames支持多种数据源构建,包括:结构化数据文件Parquet、JSON)加载、Hive表读取、外部数据库读取、现有RDD转化,以及SQLContext运行SQL查询结果创建DataFrame,如DataFrame数据来源 新的DataFrame API一方面大幅度降低了开发者学习门槛,同时支持Scala、Java、Python和R语言,且支持通过Spark Shell、Pyspark Shell和SparkR Shell提交任务。由于来源于SchemaRDD,DataFrame天然适用于分布式大数据场景。
SQL处理原理:
属于核心Spark API的扩展,它支持高吞吐量和容错的实时流数据处理,它可以接受来自Kafka、Flume、Twitter、ZeroMQ或TCP Socket的数据源,使用复杂的算法表达和高级功能来进行处理,如Map、Reduce、Join、Window等,处理的结果数据能够存入文件系统、数据库。还可以直接使用内置的机器学习算法、图形处理算法来处理数据。
Spark Streaming的数据处理流程如图所示,接收到实时数据后,首先对数据进行分批次处理,然后传给Spark Engine处理,最后生成该批次最后的结果。 Spark Streaming提供一种名为离散流(DStream)的高级抽象连续数据流。DStream直接支持Kafka、Flume的数据源创建,或者通过高级操作其他DStream创建,一个DStream是一个序列化的RDD。
Spark Streaming 图示:
ML MLlib是Spark对常用的机器学习算法的实现库,同时包括相关的测试和数据生成器。MLlib目前支持4种常见的机器学习问题:二元分类、回归、聚类和协同过滤,以及一个底层的梯度下降优化基础算法。 MLlib基于RDD,天生就可以与Spark SQL、GraphX、Spark Streaming无缝集成,MLlib是MLBase的一部分,MLBase通过边界定义,力图将MLBase打造成一个机器学习平台,让机器学习开发的门槛更低,让一些并不了解机器学习的用户也能方便地使用MLBase这个工具来处理自己的数据。 MLlib支持将本地向量和矩阵存储在单个机器中,也包括有一个或更多的RDD支持的分布式矩阵。在目前的实现中,本地向量和矩阵都是为公共接口服务的简单数据模式,MLlib使用了线性代数包Breeze。在监督学习中使用到的样本在MLlib中成为标记点。 Spark MLlib架构由底层基础、算法库和应用程序三部分构成。底层基础包括Spark的运行库、进行线性代数相关技术的矩阵库和向量库。算法库包括Spark MLlib实现的具体机器学习算法,以及为这些算法提供的各类评估方法;主要实现算法包括建立在广义线性回归模型的分类和回归,以及协同过滤、聚类和决策树。在最新的Spark 1.5.0版本中还新增了基于前馈神经网络的分类器算法MultilayerPerceptronClassifier(MLPC),频繁项挖掘算法PrefixSpan、AssociationRules,实现Kolmogorov-Smirnov检验等等算法,随着版本的演进,算法库也会越来越强大。应用程序包括测试数据的生成以及外部数据的加载等功能。 Spark的ML库基于DataFrame提供高性能API,帮助用户创建和优化实用的机器学习流水线(pipeline),包括特征转换独有的Pipelines API。相比较MLlib,变化主要体现在:
1)从机器学习的Library开始转向构建一个机器学习工作流的系统,ML把整个机器学习的过程抽象成Pipeline,一个Pipeline是由多个Stage组成,每个Stage是Transformer或者Estimator。
2)ML框架下所有的数据源都是基于DataFrame,所有模型也尽量都基于Spark的数据类型表示,ML的API操作也从RDD向DataFrame全面转变。
从社交网络到语言建模,图数据规模和重要性的不断增长,推动了数不清的新型并行图系统(例如,Giraph和GraphLab)的发展。通过限制可以表达的计算类型和引入新的技术来分割和分发图,这些系统可以以高于普通的数据并行系统几个数量级的速度执行复杂的图算法,如图基于GraphX的并行图计算与其他方式的比较 GraphX是用于图和并行图计算的新Spark API。从上层来看,GraphX通过引入弹性分布式属性图(resilient distributed property graph)扩展了Spark RDD。这种图是一种伪图,图中的每个边和节点都有对应的属性。 为了支持图计算,GraphX给出了一系列基础的操作(例如,subgraph、joinVertices、和MapReduceTriplets)以及基于Pregel API的优化变体。除此之外,GraphX还包含了一个不断扩展的图算法和构建器集合,以便简化图分析的任务。
图计算处理示例:
AMPLab发布的一个R开发包,为Apache Spark提供了轻量的前端。SparkR提供了Spark中弹性分布式数据集(RDD)的API,用户可以在集群上通过R shell交互性地运行Job。例如,我们可以在HDFS上读取或写入文件,也可以使用lapply函数进行方法调用,定义对应每一个RDD元素的运算。
Tachyon是一个分布式内存文件系统,可以理解为内存中的HDFS。为了提供更高的性能,将数据存储剥离Java Heap。用户可以基于Tachyon实现RDD或者文件的跨应用共享,并提供高容错机制,保证数据的可靠性。
Mesos是一个资源管理框架,提供类似于YARN的功能。用户可以在其中插件式地运行Spark、MapReduce、Tez等计算框架的任务。Mesos会对资源和任务进行隔离,并实现高效的资源任务调度。
BlinkDB是一个用于在海量数据上进行交互式SQL的近似查询引擎。它允许用户通过在
查询准确性和查询响应时间之间做出权衡,完成近似查询。其数据的精度被控制在允许的误
差范围内。为了达到这个目标,BlinkDB的核心思想是:通过一个自适应优化框架,随着时
间的推移,从原始数据建立并维护一组多维样本;通过一个动态样本选择策略,选择一个适
当大小的示例,然后基于查询的准确性和响应时间满足用户查询需求。
Spark使用了内存分布式数据集,除了能够提供交互式查询外,还优化了迭代工作负载,在Spark SQL、Spark Streaming、MLlib、GraphX都有自己的子项目。在互联网领域,Spark在快速查询、实时日志采集处理、业务推荐、定制广告、用户图计算等方面都有相应的应用。国内的一些大公司,比如阿里巴巴、腾讯、Intel、网易、科大讯飞、百分点科技等都有实际业务运行在Spark平台上。下面简要说明Spark在各个领域中的用途。
1. 快速查询系统 基于日志数据的快速查询系统业务构建于Spark之上,利用其快速查询以及内存表等优势,能够承担大部分日志数据的即时查询工作;在性能方面,普遍比Hive快2~10倍,如果使用内存表的功能,性能将会比Hive快百倍。
2. 实时日志采集处理 通过Spark Streaming实时进行业务日志采集,快速迭代处理,并进行综合分析,能够满足线上系统分析要求。
3. 业务推荐系统 使用Spark将业务推荐系统的小时和天级别的模型训练转变为分钟级别的模型训练,有效优化相关排名、个性化推荐以及热点点击分析等。
4. 定制广告系统 在定制广告业务方面需要大数据做应用分析、效果分析、定向优化等,借助Spark快速迭代的优势,实现了在“数据实时采集、算法实时训练、系统实时预测”的全流程实时并行高维算法,支持上亿的请求量处理;模拟广告投放计算效率高、延迟小,同MapReduce相比延迟至少降低一个数量级。
5. 用户图计算 利用GraphX解决了许多生产问题,包括以下计算场景:基于度分布的中枢节点发现、基于最大连通图的社区发现、基于三角形计数的关系衡量、基于随机游走的用户属性传播等。
随着企业数据量的增长,对大数据的处理和分析已经成为企业的迫切需求。Spark作为Hadoop的替代者,引起学术界和工业界的普遍兴趣,大量应用在工业界落地,许多科研院校开始了对Spark的研究。
在学术界,Spark得到各院校的关注。Spark源自学术界,最初是由加州大学伯克利分校的AMPLab设计开发。国内的中科院、中国人民大学、南京大学、华东师范大学等也开始对Spark展开相关研究。涉及Benchmark、SQL、并行算法、性能优化、高可用性等多个方面。在工业界,Spark已经在互联网领域得到广泛应用。互联网用户群体庞大,需要存储大数据并进行数据分析,Spark能够支持多范式的数据分析,解决了大数据分析中迫在眉睫的问题。例如,国外Cloudera、MapR等大数据厂商全面支持Spark,微策略等老牌BI厂商也和Databricks达成合作关系,Yahoo!使用Spark进行日志分析并积极回馈社区,Amazon在云端使用Spark进行分析。国内同样得到很多公司的青睐,淘宝构建Spark on Yarn进行用户交易数据分析,使用GraphX进行图谱分析。网易用Spark和Shark对海量数据进行报表和查询。腾讯使用Spark进行精准广告推荐。
下面将选取代表性的Spark应用案例进行分析,以便于读者了解Spark在工业界的应用状况:
亚马逊云计算服务AWS(Amazon Web Services)提供IaaS和PaaS服务。Heroku、
Netflix等众多知名公司都将自己的服务托管其上。AWS以Web服务的形式向企业提供IT基础设施服务,现在通常称为云计算。云计算的主要优势是能够根据业务发展扩展的较低可变成本替代前期资本基础设施费用。利用云,企业无须提前数周或数月来计划和采购服务器及其他IT基础设施,即可在几分钟内即时运行成百上千台服务器,并更快达成结果。
在Spark技术的研究与应用方面,Yahoo!始终处于领先地位,它将Spark应用于公司的各种产品之中。移动App、网站、广告服务、图片服务等服务的后端实时处理框架均采用了Spark+Shark的架构。在2013年,Yahoo!拥有72656600个页面,有上百万的商品类别,上千个商品和用户特征,超过800万用户,每天需要处理海量数据。
数据挖掘算法有时候需要迭代,每次迭代时间非常长,这是淘宝选择一个更高性能计算框架Spark的原因。Spark编程范式更加简洁也是一大原因。另外,GraphX提供图计算的能力也是很重要的。Spark的计算调度方式从Mesos到Standalone,即自建Spark计算集群。虽然Standalone方式性能与稳定性都得到了提升,但自建集群资源少,需要从云梯集群复制数据,不能满足数据挖掘与计算团队业务需求。而Spark on YARN能让Spark计算模型在云梯YARN集群上运行,直接读取云梯上的数据,并充分享受云梯YARN集群丰富的计算资源。图为Spark on YARN的架构。