flink与spark比较

原创: spark技术分享 2017-07-12

首发个人公众号spark技术分享,同步个人网站coolplayer.net,未经本人同意,禁止一切转载

我第一次接触到Flink的时候,就在想我们女人的真真需要它,大数据世界中有数不清的框架,但是我们缺少一个可以一统江湖的生态,spark现在就充当这样一个角色,那么为什么我们还需要另外一个类似的东西。

好奇之下,我们开始接触Flink,开始的时候,我发现它的一些demo看起来极其类似spark,我把它当做spark的一个模仿者,但是在我了解的足够多之后,我发现两者还是有很大区别的,Flink里面有很多自己独特的东西,我对它就充满兴趣了。

Flink的一些特性,比如实现了自己的内存管理,已经在spark中得到证明的数据集API,所以理解flink有助于我们把握大数据的未来

我这里说下我作为一个spark开发者对flink的第一印象,当然我使用spark已经两年,而使用flink只有两周,所以有可能会偏颇。

flink作为数据处理引擎的新生代,旨在统一数据处理技术栈,是不是听起来像spark,不错,flink就是那么像spark,两者都是想成为一个统一批处理,实时流处理,交互式查询,图处理,机器学习等领域的神器,flink的设计哲学和spark是一样一样的,但是实现细节上却有不同。

下面我们来对比一下两者的相同点和不同点

概念

在spark中,批处理使用RDD,流处理使用DStream(内部使用RDD实现),所有底层统一都使用RDD的抽象实现

在flink中,批处理使用Dataset,流处理使用DataStreams,听起来类似RDD和DStreams,但其实不是,不同点在于

  • flink中的Dataset代表着执行计划,而spark的RDD仅仅是一个java对象,spark中的数据帧才有执行计划,flink和spark两者最基础的东西,数据集和RDD,是不同的。一个是经过优化数据集类似火花中经过优化的数据帧概念
  • 在spark中,DStream和Dataframe等都是基于RDD的封装,然而flink中的Dataset和DataStream则是独立实现的,尽管两者间尽量保持相同的API,但是你很难统一起来,至少没有spark中那样优雅,这个大方向,flink能不能做到就难说了。我们不能统一DataSet和DataStreams,尽管flink有和spark相同的抽象,但是内部实现是不同的。

内存管理

spark 1.5之前,spark一直都是使用java jvm堆来保存对象,虽然有利于启动项目,但是经常会产生OOM和gc问题,所以1.5开始,spark开始引入自己管理内存的钨项目。

Flink从第一天起就自己管理内存,spark就是从这学的吧,不仅保存数据使用二进制数据,而且可以直接在二进制数据上进行操作.spark 1.5开始也可以直接在二进制数据进行数据帧API提供的操作了。自己管理内存,直接使用分配的二进制数据而不是JVM对象可以得到更高的性能和更好的资源利用。

实现语言

spark使用scala实现,提供JAVA,Pyton和R等语言的API,

flink由java实现,同时提供scala api。
在语言的选择方面,spark是优于flink的,因为scala更抽象层次更高,更利于表达数据处理流程。

API

Spark和Flink都模仿了scala集合的处理API,所以两者看起来比较像,下面是两个人的wordcount演示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// Spark wordcount
object WordCount {

def main(args: Array[String]) {

val env = new SparkContext("local","wordCount")

val data = List("hi","how are you","hi")

val dataSet = env.parallelize(data)

val words = dataSet.flatMap(value => value.split("\\s+"))

val mappedWords = words.map(value => (value,1))

val sum = mappedWords.reduceByKey(_+_)

println(sum.collect())

}

}
// Flink wordcount
object WordCount {

def main(args: Array[String]) {

val env = ExecutionEnvironment.getExecutionEnvironment

val data = List("hi","how are you","hi")

val dataSet = env.fromCollection(data)

val words = dataSet.flatMap(value => value.split("\\s+"))

val mappedWords = words.map(value => (value,1))

val grouped = mappedWords.groupBy(0)

val sum = grouped.sum(1)

println(sum.collect())
}

}

尽管不知道是否是巧合,两者给用户提供的API是极其类似的,有利于我们在两者切换,看起来这种API应该就是数据处理流的标准了吧,scala的创建者Martin Odersky,之前也表明过类似观点。

流式处理

在spark的眼里,流是特殊的批,在flink眼里,批量是特殊的流,主要的区别在于

  • 实时vs准实时,flink提供事件事件级别的延迟,可以认为是实时的,类似于storm的模型,而spark中,是微批处理,不能提供事件级别的延迟,我们可以称之为准实时。

尽管大部分应用准实时就可以满足需求,但是也有一些必须要是事件级别的实时,这时候我们应该使用风暴而不是火花流,当然flink也是个不错的选择。

  • 统一历史数据和实时数据的能力,微批处理的优势就是我们可以轻易的统一历史数据和实时数据的处理,在火花中,由于两者底层使用了相同的RDD抽象,所以很容易做到这一点,在flink中,批处理和流式处理使用不同的api,所以很难统一历史数据和实时数据。对于有些应用来说,两者保持统一是很有必要的,这里就应该使用spark。
  • 灵活的窗口处理支持,因为spark是微批处理,所以不太容易支持窗口,只能根据处理时间对多个批次进行窗口处理。

flink则可以灵活的支持窗口,支持带有事件时间的窗口(Window)操作是flink的亮点,你可以选择使用处理时间还是事件时间进行窗口操作,这种灵活性是spark所不如的。

SQL接口

spark-sql是spark中进展最活跃的部分,spark提供hive查询语言,也提供在Dataframe上对结构化数据进行DSL语法查询,成熟稳定易扩展的API,也可以在实时数据上进行使用。

Flink中则只提供了数据帧上的DSL语法的查询,

所以在sql查询上,spark是有显着优势的。

数据源整合

spark的数据接入api极其易用,数据源良好的支持,使一些NoSQL数据库,镶木地板,ORC在spark中都是一等公民,提供了一些更高级的特性,比如在数据源上进行预测下推优化,

Flink则是严重依赖map / reduce中的InputFormat api进行数据整合,对于拉取数据是够了,但是没法进行更好的优化,所以flink是落后的。

流作为平台与批处理作为平台

spark来自于Map / Reduce时代,崇尚运算追着数据走,数据可以是内存中的数组,也可以是磁盘中的文件,可以进行很好的容错。

Flink的模型中,数据是追着运算走的,算子位于节点上,数据从中流过,类似于akka-streams中的概念,

我不能肯定哪种模型代表着大数据的未来,

打赏
  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2018-2020 丁振莹
  • 访问人数: | 浏览次数:

你的每一分支持,是我努力下去的最大的力量 ٩(๑❛ᴗ❛๑)۶

支付宝
微信