给 spark 开发者介绍下Flink :Flink vs Spark
Posted spark技术分享
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了给 spark 开发者介绍下Flink :Flink vs Spark相关的知识,希望对你有一定的参考价值。
我第一次接触到 Flink的时候, 就在想我们究竟是否真的需要它,大数据世界中有数不清的框架, 但是我们缺少一个可以一统江湖的生态, spark 现在就充当这样一个角色, 那么为什么我们还需要另外一个类似的东西。
好奇之下, 我们开始接触 Flink, 开始的时候, 我发现它的一些demo看起来极其类似spark,我把它当做spark的一个模仿者, 但是在我了解的足够多之后, 我发现两者还是有很大区别的, Flink 里面有很多自己独特的东西, 我对它就充满兴趣了。
Flink的一些特性, 比如实现了自己的内存管理, 已经在 spark中得到证明的 dataset API , 所以理解 flink 有助于我们把握大数据的未来
我这里说下我作为一个spark 开发者对 flink的第一印象, 当然我使用 spark 已经两年, 而使用flink只有两周, 所以有可能会偏颇。
什么是 flink
flink 作为数据处理引擎的新生代, 旨在统一数据处理技术栈, 是不是听起来像spark, 不错, flink 就是那么像 spark, 两者都是想成为一个统一批处理、实时流处理、交互式查询,图处理、机器学习等领域的神器, flink的设计哲学和 spark 是一样一样的, 但是实现细节上却有不同。
下面我们来对比一下两者的相同点和不同点
概念
在 spark 中, 批处理使用 RDD, 流处理使用 DStream(内部使用RDD实现), 所有底层统一都使用 RDD的抽象实现
在 flink 中, 批处理使用 Dataset, 流处理使用 DataStreams, 听起来类似 RDD 和 DStreams, 但其实不是, 不同点在于
flink 中的 Dataset 代表着执行计划, 而spark 的 RDD 仅仅是一个 java 对象,spark中的dataframes 才有执行计划, flink 和 spark 两者最基础的东西, Dataset 和 RDD, 是不同的。 一个是经过优化器优化的, 一个没有。 flink 中的 Dataset 类似 spark 中经过优化的 Dataframe 概念, spark 1.6 中引入的dataset(跟 flink 中的 Dataset 重名了,两者类似) 最终应该会代替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 开始引入 自己管理内存的 tungsten 项目。
Flink 从第一天起就自己管理内存, spark 就是从这学的吧, 不仅保存数据使用 binary data, 而且可以直接在binary data 上进行操作。 spark 1.5 开始也可以直接在binary data 进行 dataframe API 提供的操作了。 自己管理内存, 直接使用分配的binary data而不是JVM objects 可以得到更高的性能 和 更好的资源利用。
实现语言
spark 使用 scala 实现, 提供 JAVA, Pyton 和R等语言的API,
flink 由java 实现, 同时提供 scala api。
在语言的选择方面, spark 是优于 flink的, 因为scala 更抽象层次更高, 更利于表达数据处理流程。
API
Spark 和 Flink 都模仿了 scala 集合的处理 API, 所以两者看起来比较像, 下面是 两者的 wordcount demo
// 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 的眼里, streaming 是特殊的 batch, 在 flink 眼里, batch 是特殊的 streaming, 主要的区别在于
实时 vs 准实时 ,flink 提供 event 事件级别的延迟, 可以认为是实时的, 类似于 storm 的模型, 而 spark 中, 是微批处理, 不能提供事件级别的延迟, 我们可以称之为准实时。
尽管大部分应用准实时就可以满足需求, 但是也有一些必须要是事件级别的实时, 这时候我们应该使用 storm 而不是 spark streaming, 当然 flink 也是个不错的选择。
统一历史数据和实时数据的能力, 微批处理的优势就是我们可以轻易的统一历史数据和实时数据的处理, 在 spark中, 由于两者底层使用了相同的RDD 抽象, 所以很容易做到这一点, 在flink 中, 批处理和流式处理使用不同的api, 所以很难统一历史数据和实时数据。 对于有些应用来说, 两者保持统一是很有必要的, 这里就应该使用 spark。
灵活的窗口处理支持, 因为 spark 是微批处理, 所以不太容易支持窗口, 只能根据 process time 对多个 batches 进行窗口处理。
flink 则可以灵活的支持窗口, 支持带有事件时间的窗口(Window)操作是flink 的亮点, 你可以选择使用处理时间还是事件时间进行窗口操作, 这种灵活性是 spark 所不如的。
SQL 接口
spark-sql 是spark中进展最活跃的部分, spark 提供 hive 查询语言, 也提供 在 Dataframe 上对 structured 数据进行 DSL语法查询, 成熟稳定易扩展的 API, 也可以在 实时数据上进行使用。
Flink 中则只提供了 dataframe 上的 DSL语法的查询,
所以在 sql 查询上, spark 是有显著优势的。
数据源整合
spark 的数据接入api 极其易用, 数据源良好的支持, 使一些 NoSQL 数据库, parquet, ORC 在 spark 中都是一等公民, 提供了一些更高级的特性, 比如在数据源上进行 预测下推优化,
Flink 则是严重依赖 map/reduce 中的 InputFormat api 进行数据整合, 对于拉取数据是够了, 但是没法进行更好的优化, 所以 flink 是落后的。
Stream as platform vs Batch as Platform
spark 来自于 Map/Reduce 时代, 崇尚 运算追着数据走, 数据可以是内存中的数组, 也可以是磁盘中的文件, 可以进行很好的容错。
Flink 的模型中, 数据是追着运算走的, 算子位于节点上, 数据从中流过, 类似于 akka-streams 中的概念,
我不能肯定哪种模型代表着大数据的未来,
欢迎关注 spark技术分享:
以上是关于给 spark 开发者介绍下Flink :Flink vs Spark的主要内容,如果未能解决你的问题,请参考以下文章
Flink 源码解析 —— 深度解析 Flink 序列化机制