【迁移】Flink vs Spark
前几周我出于好奇花了一些时间研究了下flink。当我一看到标准示例就立刻发现他和Spark其中一个例子很像。于是我认为这只是模仿实现了spark功能的另一个框架。但是随着我研究的深入,越来越清晰地发觉,有些藏匿在这个看起来很相似的API后的一些新颖的想法使得flink区别于spark。我被这些想法吸引了,并且花越来越多的时间搞懂和探索。
许多flink的想法像自定义内存管理,dataset API都已经在Spark中实现了,并且被证明是很不错的。所以搞明白flink可以帮助我们搞清楚未来分布式数据处理方面的趋势信息。
在这篇博客中我尝试作为一名spark开发者来阐述我对于Apche flink的第一印象。这个审视是我作为一名从事Spark开发2年而仅花了2-3周的时间玩了玩Apache flink的人的一些个人见解。所以带着批判的思维看待我现在做的事吧~
什么是Apache Flink?
Apache Flink是新一代的大数据处理引擎,他致力于统一不同数据载入。他听起来像是Apache Spark吗?确实是。Flink尝试去定位Spark尝试去解决的课题。这两个系统都是向着建立单一平台,在这个平台上可以运行诸如批处理,流式,交互计算,图计算,机器学习等。所以flink和Spark的思想体系是很接近的。但是他们在实现的细节方面有着很大的区别。
Apache Spark VS Apache Flink
1 抽象概念
在Spark里,我们使用RDD抽象模型来运行批处理,使用DStream来创建流计算任务,这些都是RDD本身带有的。所以我们在Spark中展示的所有的数据都使用了RDD。
在flink中,我们使用Dataset抽象模型来运行批处理,使用DataStreams创建流应用。他们听起来比较像RDD和DStreams但其实不同。不同点表现在:
Dataset作为运行时的计划体现
在spark中RDD在运行时阶段被当作java对象。通过Tungsten的介绍,他的变化是微乎其微的。而Apache flink的Dataset是作为逻辑计划执行的。听着熟悉吗?是的,他们就像是Spark中的dataframes。所以在flink中你可以将Dataframe像API一样使用,作为使用优化器优化过的一等类公民。但是在Spark RDD中没有任何这样的优化存在。
flink里的Dataset就像是在执行前优化了的Spark Dataframe API。
在spark 1.6中,dataset API才加入spark,这也将会最终取代RDD。
Dataset和DataStream是独立的API
在Spark中像DStream和Dataframe都是建立在RDD抽象基础之上的。但是在flink中,Dataset和DataStream是建立在
我们不能将DataSet和DataStreams结合起来,像RDD和DStreams一样。
故即使flink和spark拥有差不多的抽象组件,他们的实现还是有很大差异的。
2 内存管理
直到spark1.5,Spark才开始使用Java堆来缓存数据。尽管对于一个项目来说很容易开始,但结果不是报OOM错误就是gc停止了。所以自从1.5以来,spark步入自定义内存管理阶段,这个项目叫做tangsten。
Flink总有一天也会自定义内存管理。实际上他还是Spark往这个方向迈进的一个灵感。不仅flink将他的数据存储在自定义的二进制格式中,他直接操作二进制数据。在spark中,自从1.5开始,所有的dataframe操作都是直接在tungsten二进制数据中执行的。
在JVM上的自定义内存管理有更好的表现和更好的资源利用率。
3 实现语言
Spark是用Scala实现的。他也提供其他语言的APIs,这些语言有Java,Python和R。而Flink是用Java实现的。他有提供Scala的API。
所以语言方面的选择Spark要优于flink。虽然在一些flink的scala API里,是用java实现的抽象。我认为当有更多用户的时候这一点将会得到改善。我对于Spark和Flink中的java API没有太多想法,因为我早已经转向了Scala。
4 API
Spark和Flink有着相似的scala集合API。所以从表面上看两个API都差不多。下面是用RDD和Dataset API编写的word count程序。
我不是很确定,这到底是巧合还是故意的,有着这么相似的API有助于在两个框架中轻易地切换。好像在不久的将来集合API将会成为创建数据通道的标准API。甚至是Scala的发明人,Martin Odersky都认同了这个事实。
5 流
Apache Spark将流视为快速的批处理工具。而Apache flink将批处理视为流处理的特殊情形。 这两种都有着优雅的实现方式。不过两种接近的实现的不同点在于
实时VS准实时
Apache flink提供基于事件的处理,也叫做实时流处理。这很像Storm模型。
而在Spark中我们提供的最小批量处理不支持切分到事件级别粒度。这种成为准实时。
Spark Streaming是更快的批处理,Flink批处理绑定在流处理中。
尽管准实时系统没什么毛病,还是有些系统需要基于事件的实时处理的。这些系统更适合用storm而不是Spark Streaming。这两者之间flink有非常有趣的选择。
结合历史数据和流的能力
将流处理当作更快的批处理的一点好处在于,我们可以在两种情形之间做相同的抽象。Spark在结合批和流数据上有着极佳的支持因为RDD抽象模型。
在flink中,批和流不共享同样的api抽象层。所以即使有途径结合基于数据流的历史文件,但他没有Spark来的那么简洁。
在许多应用中这种能力还是很重要的。在这些应用中Spark代替了Flink流的地位。
多样的窗口函数
由于最小批的特性,Spark中对窗口函数的支持比较局限,直到现在。你只能在基于处理时间中将批进行窗口化。
相比于其他系统Flink提供了丰富的窗口系统。窗口函数也是flink流API的重中之重。他提供基于处理时间,数据时间,空记录等的窗口函数。这个多样性使得flink流API相比于spark要强大的多。
我不确定将这样的API带给Spark会不会很容易,不过直到现在flink有着相比Spark streaming更加有优势的窗口API。
SQL interface
目前来看Spark库中最热门的当属spark-sql了。Spark不仅提供了像查询语言一样的Hive,还有用来查询结构数据的DSL一样的Dataframe。这是成熟的API并且在批处理和流世界中广泛地应用。
现在Flink的Table API只支持像DSL的dataframe,它仍然在beta阶段。据称有计划将sql接口加进去,但是不确定什么时候能够落地到框架中。
所以现在Spark相比于flink有着不错的sql支持。我认为flink会后来居上的。
Data source Integration
Spark数据源API是这个框架中最好的API了。数据源API使得像NoSQL数据库,parquet,ORC这些不错的数据源作为spark中的第一等公民。当然这个API提供了像在源码级别中预测的操作的能力。
Flink还是很依赖于map/reduce inputFormat去做数据源的集成。尽管他是足够好的推送数据的API,但是它不能充分利用好源的能力。所以flink在数据源集成方面落后了一些。
Iterative processing
Spark的一个最经常被谈论到的特征就是高效处理机器学习的能力。由于可以进行内存计算,和其他的一些实现细节,以至于它确实是实现ML算法的强大平台。
尽管ML算法在spark中是表现为直接非周期图的循环数据流。正常的没有分布式处理系统鼓励去做复杂的循环数据流运算。
不过flink和其他框架比起来也没有多大差别。他支持在运行时控制循环依赖的图计算。相比于DAG他用了非常搞笑的方式去表现ML算法。所以Flink支持在本地平台的迭代。结果是相比于DAG的方法他更具备可扩展性和高性能。
我希望spark也能开始在框架中支持这个,这将会大大促进ML协会的发展。
Stream as platform vs Batch as Platform
结论
最后总结下,Spark是更加成熟和完善的框架相比于Flink来说。但是flink带来了譬如自定义的内存管理,像表一样的data set API这些奇妙的想法。Spark协会认识到这点,并且把他应用到spark中。这么看来flink是推动了大数据处理向下一个层次的发展。所以了解flink API和内在的机制可以帮助你了解在技术落地到Spark之前的这个新的流计算范例。
版权声明: 本文为 InfoQ 作者【罗琦】的原创文章。
原文链接:【http://xie.infoq.cn/article/24aeca17b90d146148bd1ad14】。文章转载请联系作者。
评论