Spark2.X干货(一) 之前世今生
Spark2.X干货(一) 之前世今生
人若能转世,世间若真有轮回,那么,我的爱,我们前生曾经是什么?
席慕容 《前缘》
概述
-
Spark是什么?
Spark,是一种通用的大数据计算框架,正如传统大数据技术 Hadoop的MapReduce、Hive引擎,以及Storm流式实时计算引擎等。
Spark包含了大数据领域常见的各种计算框架:比如Spark Core用于离线计算,Spark SQL用于交互式查询,Spark Streaming用于实时流式计算,Spark MLlib用于机器学习,Spark GraphX用于图计算。
Spark主要用于大数据的计算,而Hadoop以后主要用于大数据的存储(比如HDFS、Hive、HBase等),以及资源调度(Yarn)。
Spark+Hadoop的组合,是未来大数据领域最热门的组合,也是最有前景的组合!
-
介绍
Spark,是一种"One Stack to rule them all"的大数据计算框架,期望使用一个技术堆栈就完美地解决大数据领域的各种计算任务。Apache官方,对Spark的定义就是:通用的大数据快速处理引擎。
Spark使用Spark RDD、Spark SQL、Spark Streaming、MLlib、GraphX成功解决了大数据领域中,离线批处理、交互式查询、实时流计算、机器学习与图计算等最重要的任务和问题。
Spark除了一站式的特点之外,另外一个最重要的特点,就是基于内存进行计算,从而让它的速度可以达到MapReduce、Hive的数倍甚至数十倍!
现在已经有很多大公司正在生产环境下深度地使用Spark作为大数据的计算框架,包括eBay、Yahoo!、BAT、网易、京东、华为、大众点评、优酷土豆、搜狗等等。
Spark同时也获得了多个世界顶级IT厂商的支持,包括IBM、Intel等。
-
整体架构
-
历史
2009年由Matei Zaharia在加州大学柏克莱分校AMPLab开创
2010年透过BSD许可协议开源发布。
2013年,该项目被捐赠给Apache软件基金会并切换许可协议至Apache2.0。
2014年2月,Spark成为Apache的顶级项目。
2014年11月,Databricks团队使用Spark 刷新数据排序世界记录。
-
特点
速度快:
Spark基于内存进行计算(当然也有部分计算基于磁盘,比如shuffle)。容易上手开发:
Spark的基于RDD的计算模型,比Hadoop的基于Map-Reduce的计算模型要更加易于理解,更加易于上手开发,实现各种复杂功能,比如二次排序、topn等复杂操作时,更加便捷。超强的通用性:
Spark提供了Spark RDD、Spark SQL、Spark Streaming、Spark MLlib、Spark GraphX等技术组件,可以一站式地完成大数据领域的离线批处理、交互式查询、流式计算、机器学习、图计算等常见的任务。集成Hadoop:
Spark并不是要成为一个大数据领域的“独裁者”,一个人霸占大数据领域所有的“地盘”,而是与Hadoop进行了高度的集成,两者可以完美的配合使用。Hadoop的HDFS、Hive、HBase负责存储,YARN负责资源调度;Spark复杂大数据计算。实际上,Hadoop+Spark的组合,是一种“double win”的组合。极高的活跃度:
Spark目前是Apache基金会的顶级项目,全世界有大量的优秀工程师是Spark的committer。并且世界上很多顶级的IT公司都在大规模地使用Spark。
-
特色
Java、Scala、Python和R APIs。
可扩展至超过8000个结点
能够在存储器内缓存数据集以进行交互式数据分析。
Scala或Python中的交互式命令行接口可降低横向扩展数据探索的反应时间。
Spark Streaming对即时数据流的处理具有可扩展性、高吞吐量、可容错性等特点。
Spark SQL支持结构化和关系式查询处理(SQL)。
MLlib机器学习算法和Graphx图形处理算法的高端库。
-
Spark VS MapReduce
MapReduce能够完成的各种离线批处理功能,以及常见算法(比如二次排序、topn等),基于Spark RDD的核心编程,都可以实现,并且可以更好地、更容易地实现。而且基于Spark RDD编写的离线批处理程序,运行速度是MapReduce的数倍,速度上有非常明显的优势。
Spark相较于MapReduce速度快的最主要原因就在于,MapReduce的计算模型太死板,必须是map-reduce模式,有时候即使完成一些诸如过滤之类的操作,也必须经过map-reduce过程,这样就必须经过shuffle过程。而MapReduce的shuffle过程是最消耗性能的,因为shuffle中间的过程必须基于磁盘来读写。而Spark的shuffle虽然也要基于磁盘,但是其大量transformation操作,比如单纯的map或者filter等操作,可以直接基于内存进行pipeline操作,速度性能自然大大提升。但是Spark也有其劣势。由于Spark基于内存进行计算,虽然开发容易,但是真正面对大数据的时候(比如一次操作针对10亿以上级别),在没有进行调优的情况下,可能会出现各种各样的问题,比如OOM内存溢出等等。导致Spark程序可能都无法完全运行起来,就报错挂掉了,而MapReduce即使是运行缓慢,但是至少可以慢慢运行完。
此外,Spark由于是新崛起的技术新秀,因此在大数据领域的完善程度,肯定不如MapReduce,比如基于HBase、Hive作为离线批处理程序的输入输出,Spark就远没有MapReduce来的完善。实现起来非常麻烦。
-
Spark SQL VS Hive
Spark SQL实际上并不能完全替代Hive,因为Hive是一种基于HDFS的数据仓库,并且提供了基于SQL模型的,针对存储了大数据的数据仓库,进行分布式交互查询的查询引擎。
严格的来说,Spark SQL能够替代的,是Hive的查询引擎,而不是Hive本身,实际上即使在生产环境下,Spark SQL也是针对Hive数据仓库中的数据进行查询,Spark本身自己是不提供存储的,自然也不可能替代Hive作为数据仓库的这个功能。
Spark SQL的一个优点,相较于Hive查询引擎来说,就是速度快,同样的SQL语句,可能使用Hive的查询引擎,由于其底层基于MapReduce,必须经过shuffle过程走磁盘,因此速度是非常缓慢的。很多复杂的SQL语句,在hive中执行都需要一个小时以上的时间。而Spark SQL由于其底层基于Spark自身的基于内存的特点,因此速度达到了Hive查询引擎的数倍以上。
但是Spark SQL由于与Spark一样,是大数据领域的新起的新秀,因此还不够完善,有少量的Hive支持的高级特性,Spark SQL还不支持,导致Spark SQL暂时还不能完全替代Hive的查询引擎。而只能在部分Spark SQL功能特性可以满足需求的场景下,进行使用。
而Spark SQL相较于Hive的另外一个优点,就是支持大量不同的数据源,包括hive、json、parquet、jdbc等等。此外,Spark SQL由于身处Spark技术堆栈内,也是基于RDD来工作,因此可以与Spark的其他组件无缝整合使用,配合起来实现许多复杂的功能。比如Spark SQL支持可以直接针对hdfs文件执行sql语句!
-
Spark Streaming VS Storm
Spark Streaming与Storm都可以用于进行实时流计算。但是他们两者的区别是非常大的。其中区别之一,就是,Spark Streaming和Storm的计算模型完全不一样,Spark Streaming是基于RDD的,因此需要将一小段时间内的,比如1秒内的数据,收集起来,作为一个RDD,然后再针对这个batch的数据进行处理。而Storm却可以做到每来一条数据,都可以立即进行处理和计算。因此,Spark Streaming实际上严格意义上来说,只能称作准实时的流计算框架;而Storm是真正意义上的实时计算框架。
此外,Storm支持的一项高级特性,是Spark Streaming暂时不具备的,即Storm支持在分布式流式计算程序(Topology)在运行过程中,可以动态地调整并行度,从而动态提高并发处理能力。而Spark Streaming是无法动态调整并行度的。但是Spark Streaming也有其优点,首先Spark Streaming由于是基于batch进行处理的,因此相较于Storm基于单条数据进行处理,具有数倍甚至数十倍的吞吐量。
此外,Spark Streaming由于也身处于Spark生态圈内,因此Spark Streaming可以与Spark Core、Spark SQL,甚至是Spark MLlib、Spark GraphX进行无缝整合。流式处理完的数据,可以立即进行各种map、reduce转换操作,可以立即使用sql进行查询,甚至可以立即使用machine learning或者图计算算法进行处理。这种一站式的大数据处理功能和优势,是Storm无法匹敌的。
因此,综合上述来看,通常在对实时性要求特别高,而且实时数据量不稳定,比如在白天有高峰期的情况下,可以选择使用Storm。但是如果是对实时性要求一般,允许1秒的准实时处理,而且不要求动态调整并行度的话,选择Spark Streaming是更好的选择。
-
Spark VS Flink
抽象 Abstraction
Spark中,对于批处理我们有RDD,对于流式,我们有DStream,不过内部实际还是RDD.所以所有的数据表示本质上还是RDD抽象。 后面我会重点从不同的角度对比这两者。在Flink中,对于批处理有DataSet,对于流式我们有DataStreams。看起来和Spark类似,他 们的不同点在于:Dataset在运行时是表现为运行计划(runtime plans)
在Spark中,RDD在运行时是表现为java objects的。通过引入Tungsten,这块有了些许的改变。但是在Flink中是被表现为logical plan(逻辑计划)的,听起来很熟悉?没错,就是类似于Spark中的dataframes。所以在Flink中你使用的类Dataframe api是被作为第一优先级来优化的。但是相对来说在Spark RDD中就没有了这块的优化了。
Flink中的Dataset,对标Spark中的Dataframe,在运行前会经过优化。在Spark 1.6,dataset API已经被引入Spark了,也许最终会取代RDD 抽象。
Dataset和DataStream是独立的API
在Spark中,所有不同的API,例如DStream,Dataframe都是基于RDD抽象的。但是在Flink中,Dataset和 DataStream是同一个公用的引擎之上两个独立的抽象。所以你不能把这两者的行为合并在一起操作,当然,Flink社区目前在朝这个方向努力(https://issues.apache.org/jira/browse/Flink-2320),但是目前还不能轻易断言最后的结果。
内存管理
一直到1.5版本,Spark都是试用java的内存管理来做数据缓存,明显很容易导致OOM或者gc。所以从1.5开始,Spark开始转向精确的控制内存的使用,这就是tungsten项目了。
而Flink从第一天开始就坚持自己控制内存试用。这个也是启发了Spark走这条路的原因之一。Flink除了把数据存在自己管理的内存以 外,还直接操作二进制数据。在Spark中,从1.5开始,所有的dataframe操作都是直接作用在tungsten的二进制数据上。
语言实现
Spark是用scala来实现的,它提供了Java,Python和R的编程接口。Flink是java实现的,当然同样提供了Scala API
所以从语言的角度来看,Spark要更丰富一些。因为我已经转移到scala很久了,所以不太清楚这两者的java api实现情况。API
Spark和Flink都在模仿scala的collection API.所以从表面看起来,两者都很类似。下面是分别用RDD和DataSet API实现的word count
不知道是偶然还是故意的,API都长得很像,这样很方便开发者从一个引擎切换到另外一个引擎。我感觉以后这种Collection API会成为写data pipeline的标配。
Steaming
Spark把streaming看成是更快的批处理,而Flink把批处理看成streaming的special case。这里面的思路决定了各自的方向,其中两者的差异点有如下这些:
实时 vs 近实时的角度
Flink提供了基于每个事件的流式处理机制,所以可以被认为是一个真正的流式计算。它非常像storm的model。
而Spark,不是基于事件的粒度,而是用小批量来模拟流式,也就是多个事件的集合。所以Spark被认为是近实时的处理系统。
Spark streaming 是更快的批处理,而Flink Batch是有限数据的流式计算。
虽然大部分应用对准实时是可以接受的,但是也还是有很多应用需要event level的流式计算。这些应用更愿意选择storm而非Spark streaming,现在,Flink也许是一个更好的选择。SQL interface
目前Spark-sql是Spark里面最活跃的组件之一,Spark提供了类似Hive的sql和Dataframe这种DSL来查询结构化 数据,API很成熟,在流式计算中使用很广,预计在流式计算中也会发展得很快。至于Flink,到目前为止,Flink Table API只支持类似DataFrame这种DSL,并且还是处于beta状态,社区有计划增加SQL 的interface,但是目前还不确定什么时候才能在框架中用上。所以这个部分,Spark胜出。
外部数据源的整合
Spark的数据源 API是整个框架中最好的,支持的数据源包括NoSql db,parquet,ORC等,并且支持一些高级的操作,例如predicate push down。Flink目前还依赖map/reduce InputFormat来做数据源聚合。这一场Spark胜
Iterative processing
Spark对机器学习的支持较好,因为可以在Spark中利用内存cache来加速机器学习算法。但是大部分机器学习算法其实是一个有环的数据流,但是在Spark中,实际是用无环图来表示的,一般的分布式处理引擎都是不鼓励试用有环图的。但是 Flink这里又有点不一样,Flink支持在runtime中的有环数据流,这样表示机器学习算法更有效而且更有效率。这一点Flink胜出。
Stream as platform vs Batch as Platform
Spark诞生在Map/Reduce的时代,数据都是以文件的形式保存在磁盘中,这样非常方便做容错处理。Flink把纯流式数据计算引入大 数据时代,无疑给业界带来了一股清新的空气。这个idea非常类似akka-streams这种。成熟度目前的确有一部分吃螃蟹的用户已经在生产环境中使 用Flink了,不过从我的眼光来看,Flink还在发展中,还需要时间来成熟。
结论
目前Spark相比Flink是一个更为成熟的计算框架,但是Flink的很多思路很不错,Spark社区也意识到了这一点,并且逐渐在采用Flink中的好的设计思路,所以学习一下Flink能让你了解一下Streaming这方面的更迷人的思路。
-
Spark目前在国内的现状与展望
Spark目前在国内正在飞速地发展,并且在很多领域,以及慢慢开始替代传统得一些基于Hadoop的组件。比如BAT、京东、搜狗等知名的互联网企业,都在深度的,大规模地使用Spark。
国内的招聘需求目前来说,由于大部分还是大公司在使用Spark,因此大部分中小型企业,还是主要在使用Hadoop进行大数据处理。在招聘时,还是主要以hadoop工程师为主。Spark以及Storm的招聘还是相对Hadoop来说,会少一些。
但是,能够较为全面地对Spark有一个感性得认识,就能意识到,Spark在大数据领域中,是未来的一个趋势和方向。随着Spark、Spark SQL以及Spark Streaming慢慢成熟,就会慢慢替代掉Hadoop的MapReduce、Hive查询等。大家可以想想,如果两者都能够实现相同的功能,而Spark甚至以后还可以做的更好,速度要快好几倍,甚至好几十倍。那么还有谁会愿意使用MapReduce或Hive查询引擎呢?
实际上,根据我在国内一线互联网公司这几年的工作和观察,以及通过与行业内各个规模公司的朋友交流,认为,未来的主流,一定是hadoop+Spark的这种组合,double win的格局。hadoop的特长,就是hdfs,分布式存储,基于此之上的是Hive作为大数据的数据仓库,HBase作为大数据的实时查询NoSQL数据库,YARN作为通用的资源调度框架;而Spark,则发挥它的特长,将各种各样的大数据计算模型汇聚在一个技术堆栈内,对hadoop上的大数据进行各种计算处理!
因此,大家也可以看到,Spark目前正在变得越来越火爆,招聘的企业正在越来越多,而且目前国内spark人才可以说是稀缺!!!在目前,以及未来,完全供不应求!因此这种趋势,以及这种现状,就决定了。
Spark的发展会结合硬件的发展趋势。首先,内存会变得越来越便宜,256GB内存以上的机器会变得越来越常见,而对于硬盘,则SSD硬盘也将慢慢成为服务器的标配。
由于Spark是基于内存的大数据处理平台,因而在处理过程中,会因为数据存储在硬盘中,而导致性能瓶颈。随着机器内存容量的逐步增加,类似HDFS这种存储在磁盘中的分布式文件系统将慢慢被共享内存的分布式存储系统所替代,诸如同样来自伯克利大学的AMPLab实验室的Tachyon就提供了远超HDFS的性能表现。
因此,未来的Spark会在内部的存储接口上发生较大的变化,能够更好地支持SSD、以及诸如Tachyon之类的共享内存系统。
Spark学习路线
-
基础
- 大数据Spark环境搭建
- RDD介绍
- Spark基本工作原理
- Spark开发入门之编写WordCount程序
- Spark开发入门之使用本地模式进行测试
- Spark开发入门之使用spark-submit提交到集群运行(spark-submit常用参数说明)
- Spark开发入门之Spark程序开发流程总结
- Spark开发入门之spark-shell的使用(编写wordcount程序)
- 创建RDD:并行化集合、基于文件创建RDD
- 操作RDD:transformation和action,java 8和旧版本的区别,操作key-value对
- RDD常用操作全程案例实战
- RDD持久化:cache()和persist(),几种持久化策略
- 共享变量:broadcast variable、accumulator
- RDD高级编程:基于排序算法的WordCount、二次排序、topn、combineByKey
-
各组件功能介绍和使用
-
Spark内核原理
-
Spark性能调优
-
Spark SQL
-
Spark Streaming
-
MLlib
-
GraphX