赞
踩
Spark 1.x:Spark Core(RDD)、Spark SQL(SQL+Dataframe+Dataset)、Spark Streaming、Spark MLlib、Spark Graphx
Spark 2.x:Spark Core(RDD)、Spark SQL(ANSI-SQL+Subquery+Dataframe/Dataset)、Spark Streaming、Structured Streaming、Spark MLlib(Dataframe/Dataset)、Spark Graphx、Second Generation Tungsten Engine(Whole-stage code generation+Vectorization)
Spark 1.x到Spark 2.x,完全是一脉相承的关系,即,Spark 2.x基本上是基于Spark 1.x进行了更多的功能和模块的扩展,以及底层性能的改良。绝对不是说,Spark 2.x彻底淘汰和替代了Spark 1.x中的组件。而且实际上,对于Spark 1.x中90%以上的东西,Spark 2.x几乎都完全保留了支持和延续,并没有做任何改变。这是必须要了解的一件事情。
下面就对Spark 2.x中的每个组件都进行分析,了解组件的基本原理,以及其适用和不适用的场景。
从Spark诞生之日开始,RDD就是Spark最主要的编程接口,重要程度类似于Hadoop中的MapReduce。RDD,简单来说,就是一个不可变的分布式数据集,被分为多个partition从而在一个集群上分布式地存储。我们可以使用RDD提供的各种transformation和action算子,对RDD执行分布式的计算操作。
Spark 2.0开始,包括Structured Streaming、Spark MLlib、Spark SQL底层都开始基于Dataframe/Dataset来作为基础计算引擎,那么Spark Core/RDD是不是就要被淘汰了?回答是:不会!
Spark官方社区对于这个问题也是这个态度,Spark Core绝对不会被淘汰掉。因为Spark Core/RDD作为一种low-level的API有它的较为底层的应用场景,虽然后续这种场景会越来越少,Dataframe/Dataset API会逐渐替代原先Spark Core的一些场景,但是不可否认的是,这种场景还是存在的。此外,Dataframe/Dataset实际上底层也是基于Spark Core/RDD构建的。所以说,Spark Core/RDD是Spark生态中,不可替代的基础API和引擎,其他所有的组件几乎都是构建在它之上。未来它不会被淘汰,只是应用场景会减少而已。
Spark 2.x中,在离线批处理计算中,编程API,除了RDD以外,还增强了Dataframe/Dataset API。那么,我们到底什么时候应该使用Spark Core/RDD来进行编程呢?实际上,RDD和Dataset最大的不同在于,RDD是底层的API和内核,Dataset实际上基于底层的引擎构建的high-level的计算引擎。
Spark 2.x一方面对SQL的支持做了大幅度的增强,另一方面,也通过优化了底层的计算引擎(第二代tungsten引擎,whole-stage code generation等),提升了SQL的执行性能以及稳定性。
所以在Spark 2.x中,一方面,开始鼓励大家多使用Spark SQL的SQL支持,采用Spark SQL来编写SQL进行最常见的大数据统计分析。比如可以尝试将Hive中的运行的一些SQL语句慢慢迁移到Spark SQL上来。另外一方面,一般一个新的大版本,都是不太稳定的,因此Spark SQL虽然在功能、性能和稳定性上做了很多的增强,但是难免还是会有很多的坑。因此建议在做Hive/RDBMS(比如Oracle)到Spark SQL的迁移时,要小心谨慎,一点点迁移,同时做好踩坑的准备。
就像RDD一样,Dataframe也代表一个不可变的分布式数据集。与RDD不同的一点是,Dataframe引入了schema的概念,支持以复杂的类型作为元素类型,同时指定schema,比如Row。因此Dataframe更像是传统关系型数据库中的表的概念。为了提升开发人员对大数据的处理能力,Dataframe除了提供schema的引入,还基于Schema提供了很多RDD所不具备的high-level API,以及一些domain-specific language(特定领域编程语言)。但是在Spark 2.0中,Dataframe和Dataset合并了,Dataframe已经不是一个单独的概念了,目前仅仅只是Dataset[Row]的一个类型别名而已,你可以理解为Dataframe就是Dataset。
spark2.0Dataframe和Dataset.png
从Spark 2.0开始,Dataset有两种表现形式:typed API和untyped API。我们可以认为,Dataframe就是Dataset[Row]的别名,Row就是一个untyped类型的对象,因为Row是类似于数据库中的一行,我们只知道里面有哪些列,但是有些列即使不存在,我们也可以这对这些不存在的列进行操作。因此其被定义为untyped,就是弱类型。
而Dataset[T]本身,是一种typed类型的API,其中的Object通常都是我们自己自定义的typed类型的对象,因为对象是我们自己定义的,所以包括字段命名以及字段类型都是强类型的。目前Scala支持Dataset和Dataframe两种类型,Java仅仅支持Dataset类型,Python和R因为不具备compile-time type-safety特性,因此仅仅支持Dataframe。
Dataset API有哪些优点
错误类型 | SQL | Dataframe | Dataset |
---|---|---|---|
Syntax Error | Runtime | Compile Time | Compile Time |
Analysis Error | Runtime | Runtime | Compile Time |
什么时候应该使用Dataframe/Dataset,而不是RDD呢?
最后,实际上,Spark官方社区对RDD和Dataframe/Dataset的建议时,按照各自的特点,根据的需求场景,来灵活的选择最合适的引擎。甚至说,在一个Spark应用中,也可以将两者结合起来一起使用。
Spark Streaming是老牌的Spark流式计算引擎,底层基于RDD计算引擎。除了类似RDD风格的计算API以外,也提供了更多的流式计算语义,比如window、updateStateByKey、transform等。同时对于流式计算中重要的数据一致性、容错性等也有一定的支持。
但是Spark 2.x中也推出了全新的基于Dataframe/Dataset的Structured Streaming流式计算引擎。相较于Spark Streaming来说,其最大的不同之处在于,采用了全新的逻辑模型,提出了real-time incremental table的概念,更加统一了流式计算和离线计算的概念,减轻了用户开发的负担。同时还提供了(可能在未来提供)高度封装的特性,比如双流的全量join、与离线数据进行join的语义支持、内置的自动化容错机制、内置的自动化的一次且仅一次的强一致性语义、time-based processing、延迟数据达到的自动处理、与第三方外部存储进行整合的sink概念,等等高级特性。大幅度降低了流式计算应用的开发成本。
这里要提的一句是,首先,目前暂时建议使用Spark Streaming,因为Spark Streaming基于RDD,而且经过过个版本的考验,已经趋向于稳定。对于Structured Streaming来说,一定要强调,在Spark 2.0版本刚推出的时候,千万别在生产环境使用,因为目前官方定义为beta版,就是测试版,里面可能有很多的bug和问题,而且上述的各种功能还不完全,很多功能还没有。因此Structured Streaming的设计理念虽然非常好,但是可以在后续的版本中再考虑使用。目前可以保持关注和学习,并做一些实验即可。
Spark MLlib未来将主要基于Dataframe/Dataset API来开发。而且还会提供更多的机器学习算法。因此可以主要考虑使用其spark.ml包下的API即可。
Spark GraphX,目前发展较为缓慢,如果有图计算相关的应用,可以考虑使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。