Flink 剖析

1.概述

  在如今数据爆炸的时代,企业的数据量与日俱增,大数据产品层出不穷。今天给大家分享一款产品—— Apache Flink,目前,已是 Apache 顶级项目之一。那么,接下来,笔者为大家介绍Flink 的相关内容。

2.内容

2.1 What's Flink

  Apache Flink 是一个面向分布式数据流处理和批量数据处理的开源计算平台,它能够基于同一个Flink运行时(Flink Runtime),提供支持流处理和批处理两种类型应用的功能。现有的开源计算方案,会把流处理和批处理作为两种不同的应用类型,因为他们它们所提供的SLA是完全不相同的:流处理一般需要支持低延迟、Exactly-once保证,而批处理需要支持高吞吐、高效处理,所以在实现的时候通常是分别给出两套实现方法,或者通过一个独立的开源框架来实现其中每一种处理方案。例如,实现批处理的开源方案有MapReduce、Tez、Crunch、Spark,实现流处理的开源方案有Samza、Storm。 Flink在实现流处理和批处理时,与传统的一些方案完全不同,它从另一个视角看待流处理和批处理,将二者统一起来:Flink是完全支持流处理,也就是说作为流处理看待时输入数据流是无界的;批处理被作为一种特殊的流处理,只是它的输入数据流被定义为有界的。基于同一个Flink运行时(Flink Runtime),分别提供了流处理和批处理API,而这两种API也是实现上层面向流处理、批处理类型应用框架的基础。

  Flink 是一款新的大数据处理引擎,目标是统一不同来源的数据处理。这个目标看起来和 Spark 和类似。这两套系统都在尝试建立一个统一的平台可以运行批量,流式,交互式,图处理,机器学习等应用。所以,Flink 和 Spark 的目标差异并不大,他们最主要的区别在于实现的细节。

  下面附上 Flink 技术栈的一个总览,如下图所示:

2.2 Compare

  了解 Flink 的作用和优缺点,需要有一个参照物,这里,笔者以它与 Spark 来对比阐述。从抽象层,内存管理,语言实现,以及 API 和 SQL 等方面来赘述。

2.2.1 Abstraction

  接触过 Spark 的同学,应该比较熟悉,在处理批处理任务,可以使用 RDD,而对于流处理,可以使用 Streaming,然其世纪还是 RDD,所以本质上还是 RDD 抽象而来。但是,在 Flink 中,批处理用 DataSet,对于流处理,有 DataStreams。思想类似,但却有所不同:其一,DataSet 在运行时表现为 Runtime Plans,而在 Spark 中,RDD 在运行时表现为 Java Objects。在 Flink 中有 Logical Plan ,这和 Spark 中的 DataFrames 类似。因而,在 Flink 中,若是使用这类 API ,会被优先来优化(即:自动优化迭代)。如下图所示:

  然而,在 Spark 中,RDD 就没有这块的相关优化,如下图所示::

  另外,DataSet 和 DataStream 是相对独立的 API,在 Spark 中,所有不同的 API,比如 Streaming,DataFrame 都是基于 RDD 抽象的。然而在 Flink 中,DataSet 和 DataStream 是同一个公用引擎之上的两个独立的抽象。所以,不能把这两者的行为合并在一起操作,目前官方正在处理这种问题,详见[FLINK-2320

2.2.2 Memory

  在之前的版本(1.5以前),Spark 延用 Java 的内存管理来做数据缓存,这样很容易导致 OOM 或者 GC。之后,Spark 开始转向另外更加友好和精准的控制内存,即:Tungsten 项目。然而,对于 Flink 来说,从一开始就坚持使用自己控制内存。Flink 除把数据存在自己管理的内存之外,还直接操作二进制数据。在 Spark 1.5之后的版本开始,所有的 DataFrame 操作都是直接作用于 Tungsten 的二进制数据上。

  PS:Tungsten 项目将是 Spark 自诞生以来内核级别的最大改动,以大幅度提升 Spark 应用程序的内存和 CPU 利用率为目标,旨在最大程度上利用硬件性能。该项目包括了三个方面的改进:

  1. 内存管理和二进制处理:更加明确的管理内存,消除 JVM 对象模型和垃圾回收开销。
  2. 缓存友好计算:使用算法和数据结构来实现内存分级结构。
  3. 代码生成:使用代码生成来利用新型编译器和 CPU。

2.2.3 Program

  Spark 使用 Scala 来实现的,它提供了 Java,Python 以及 R 语言的编程接口。而对于 Flink 来说,它是使用 Java 实现的,提供 Scala 编程 API。从编程语言的角度来看,Spark 略显丰富一些。

2.2.4 API

  Spark 和 Flink 两者都倾向于使用 Scala 来实现对应的业务。对比两者的 WordCount 示例,很类似。如下所示,分别为 RDD 和 DataSet API 的示例代码:

  • RDD
1
2
3
4
5
6
7
8
9
10
11
12
// Spark WordCount
object WordCount {
  def main(args: Array[String]) {
    val env = new SparkContext("local","WordCount")
    val data = List("hi","spark cluster","hi","spark")
    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())
  }
}
  • DataSet
1
2
3
4
5
6
7
8
9
10
11
12
13
// Flink WordCount
object WordCount {
    def main(args: Array[String]) {
        val env = ExecutionEnvironment.getExecutionEnvironment
        val data = List("hello","flink cluster","hello")
        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())
    }
}

  对于 Streaming,Spark 把它看成更快的批处理,而 Flink 把批处理看成 Streaming 的特殊例子,差异如下:其一,在实时计算问题上,Flink 提供了基于每个事件的流式处理机制,所以它可以被认为是一个真正意义上的流式计算,类似于 Storm 的计算模型。而对于 Spark 来说,不是基于事件粒度的,而是用小批量来模拟流式,也就是多个事件的集合。所以,Spark 被认为是一个接近实时的处理系统。虽然,大部分应用实时是可以接受的,但对于很多应用需要基于事件级别的流式计算。因而,会选择 Storm 而不是 Spark Streaming,现在,Flink 也许是一个不错的选择。

2.2.5 SQL

  目前,Spark SQL 是其组件中较为活跃的一部分,它提供了类似于 Hive SQL 来查询结构化数据,API 依然很成熟。对于 Flink 来说,截至到目前 1.0 版本,只支持 Flink Table API,官方在 Flink 1.1 版本中会添加 SQL 的接口支持。[Flink 1.1 SQL 详情计划

3.Features

  Flink 包含一下特性:

  • 高吞吐 & 低延时
  • 支持 Event Time & 乱序事件
  • 状态计算的 Exactly-Once 语义
  • 高度灵活的流式窗口
  • 带反压的连续流模型
  • 容错性
  • 流处理和批处理共用一个引擎
  • 内存管理
  • 迭代 & 增量迭代
  • 程序调优
  • 流处理应用
  • 批处理应用
  • 类库生态
  • 广泛集成

3.1 高吞吐 & 低延时

  Flink 的流处理引擎只需要很少配置就能实现高吞吐率和低延迟。下图展示了一个分布式计数的任务的性能,包括了流数据 shuffle 过程。

3.2 支持 Event Time & 乱序事件

  Flink 支持了流处理和 Event Time 语义的窗口机制。Event time 使得计算乱序到达的事件或可能延迟到达的事件更加简单。如下图所示:

3.3 状态计算的 exactly-once 语义

  流程序可以在计算过程中维护自定义状态。Flink 的 checkpointing 机制保证了即时在故障发生下也能保障状态的 exactly once 语义。

3.4 高度灵活的流式窗口

  Flink 支持在时间窗口,统计窗口,session 窗口,以及数据驱动的窗口,窗口可以通过灵活的触发条件来定制,以支持复杂的流计算模式。

3.5 带反压的连续流模型

  数据流应用执行的是不间断的(常驻)operators。Flink streaming 在运行时有着天然的流控:慢的数据 sink 节点会反压(backpressure)快的数据源(sources)。

3.6 容错性

  Flink 的容错机制是基于 Chandy-Lamport distributed snapshots 来实现的。这种机制是非常轻量级的,允许系统拥有高吞吐率的同时还能提供强一致性的保障。

3.7 流处理和批处理共用一个引擎

  Flink 为流处理和批处理应用公用一个通用的引擎。批处理应用可以以一种特殊的流处理应用高效地运行。如下图所示:

3.8 内存管理

  Flink 在 JVM 中实现了自己的内存管理。应用可以超出主内存的大小限制,并且承受更少的垃圾收集的开销。

3.9 迭代和增量迭代

  Flink 具有迭代计算的专门支持(比如在机器学习和图计算中)。增量迭代可以利用依赖计算来更快地收敛。如下图所示:

3.10 程序调优

  批处理程序会自动地优化一些场景,比如避免一些昂贵的操作(如 shuffles 和 sorts),还有缓存一些中间数据。

3.11 流处理应用

  DataStream API 支持了数据流上的函数式转换,可以使用自定义的状态和灵活的窗口。下面示例展示了如何以滑动窗口的方式统计文本数据流中单词出现的次数。

1
2
3
4
5
6
7
8
9
10
case class Word(word: String, freq: Long)
 
val texts: DataStream[String] = ...
 
val counts = text
  .flatMap { line => line.split("\\W+") }
  .map { token => Word(token, 1) }
  .keyBy("word")
  .timeWindow(Time.seconds(5), Time.seconds(1))
  .sum("freq")

3.12 批处理应用

  Flink 的 DataSet API 可以使你用 Java 或 Scala 写出漂亮的、类型安全的、可维护的代码。它支持广泛的数据类型,不仅仅是 key/value 对,以及丰富的 operators。下面示例展示了图计算中 PageRank 算法的一个核心循环。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
case class Page(pageId: Long, rank: Double)
case class Adjacency(id: Long, neighbors: Array[Long])
 
val result = initialRanks.iterate(30) { pages =>
  pages.join(adjacency).where("pageId").equalTo("pageId") {
 
    (page, adj, out : Collector[Page]) => {
      out.collect(Page(page.id, 0.15 / numPages))
         
      for (n <- adj.neighbors) {
        out.collect(Page(n, 0.85*page.rank/adj.neighbors.length))
      }
    }
  }
  .groupBy("pageId").sum("rank")
}

3.13 类库生态

  Flink 栈中提供了提供了很多具有高级 API 和满足不同场景的类库:机器学习、图分析、关系式数据处理。当前类库还在 beta 状态,并且在大力发展。

3.14 广泛集成

  Flink 与开源大数据处理生态系统中的许多项目都有集成。Flink 可以运行在 YARN 上,与 HDFS 协同工作,从 Kafka 中读取流数据,可以执行 Hadoop 程序代码,可以连接多种数据存储系统。如下图所示:

4.总结

  以上,便是对 Flink 做一个简要的剖析认识,至于如何使用 Flink,以及其编译,安装,部署,运行等流程,较为简单,这里就不多做赘述了,大家可以在 Flink 的官网,阅读其 QuickStart 即可,[访问地址]。

5.结束语

  这篇博客就和大家分享到这里,如果大家在研究学习的过程当中有什么问题,可以加群进行讨论或发送邮件给我,我会尽我所能为您解答,与君共勉!

联系方式: 
邮箱:smartdengjie@gmail.com 
QQ群(Hadoop - 董的博客2):306184597 (已满) 
QQ群(Hadoop - 交流社区1):424769183 
温馨提示:请大家加群的时候写上加群理由(姓名+公司/学校),方便管理员审核,谢谢!

热爱生活,享受编程,与君共勉!

作者:哥不是小萝莉 [关于我

Apache Flink的更多相关文章

  1. Apache Flink初接触

    Apache Flink闻名已久,一直没有亲自尝试一把,这两天看了文档,发现在real-time streaming方面,Flink提供了更多高阶的实用函数. 用Apache Flink实现WordC ...

  2. Stream Processing for Everyone with SQL and Apache Flink

    Where did we come from? With the 0.9.0-milestone1 release, Apache Flink added an API to process rela ...

  3. Peeking into Apache Flink's Engine Room

    http://flink.apache.org/news/2015/03/13/peeking-into-Apache-Flinks-Engine-Room.html   Join Processin ...

  4. [Essay] Apache Flink:十分可靠,一分不差

    Apache Flink:十分可靠,一分不差 Apache Flink 的提出背景 我们先从较高的抽象层次上总结当前数据处理方面主要遇到的数据集类型(types of datasets)以及在处理数据 ...

  5. [Note] Apache Flink 的数据流编程模型

    Apache Flink 的数据流编程模型 抽象层次 Flink 为开发流式应用和批式应用设计了不同的抽象层次 状态化的流 抽象层次的最底层是状态化的流,它通过 ProcessFunction 嵌入到 ...

  6. Apache Flink Quickstart

    Apache Flink 是新一代的基于 Kappa 架构的流处理框架,近期底层部署结构基于 FLIP-6 做了大规模的调整,我们来看一下在新的版本(1.6-SNAPSHOT)下怎样从源码快速编译执行 ...

  7. 新一代大数据处理引擎 Apache Flink

    https://www.ibm.com/developerworks/cn/opensource/os-cn-apache-flink/index.html 大数据计算引擎的发展 这几年大数据的飞速发 ...

  8. Apache Flink 流处理实例

    维基百科在 IRC 频道上记录 Wiki 被修改的日志,我们可以通过监听这个 IRC 频道,来实时监控给定时间窗口内的修改事件.Apache Flink 作为流计算引擎,非常适合处理流数据,并且,类似 ...

  9. Apache Flink 介绍

    原文地址:https://mp.weixin.qq.com/s?__biz=MzU2Njg5Nzk0NQ==&mid=2247483660&idx=1&sn=ecf01cfc8 ...

随机推荐

  1. 解决Sublime Text3莫名的中文乱码问题

    有好几回用Sublime Text3写着中英混杂的文字的时候,会突然就弹出警告说什么编码不行,然后点击确定后,原来的中文全都乱码了: 然后即使按ctrl+z撤回也没用,重新打开也没用,用记事本的转换a ...

  2. Python学习之路——类

    类: 类是将抽象的实物进行的划分. 在现实世界中如果我们将: 人类包含:男人.女人.孩子.老人等动物类包含:小猫.小狗.小兔子等 在代码世界中我也可以分类,例如将相同功能的代码放到一起,这就是分类. ...

  3. poj 2094 多项式求和。

    /** 给出多项式 p(x) = an*x^n + an-1*x^(n-1)..... + a1*x + a0; 给定n,l,k,m 计算 x 从 l到 l+k-1 的p(x)的后m 位的平方的和 用 ...

  4. hibernate 缓存 4.3

    缓存在hibernate中是天生就有的,是一级缓存,当session关闭时一级缓存就失效了 一级缓存是内置的,生效范围是在同一个session中才行.二级缓存是需要配置才有 判断当前项在不在一级缓存中 ...

  5. Memcached初体验及原理解说

    1.简单介绍 Memcached 是一个 高性能的 分布式 内存对象缓存系统,用于动态Web应用降低数据库负载,提升性能. 2.试用场景 1.变化频繁,具有不稳定性的数据 (比方用户在线状态.在线人数 ...

  6. NYIST 914Yougth的最大化【二分搜索/Dinkelbach算法】

    转载请注明出处:http://www.cnblogs.com/KirisameMarisa/p/4187637.html 题目链接:http://acm.nyist.net/JudgeOnline/p ...

  7. iTextSharp.text的一个使用,主要用来创建PDF

    using iTextSharp.text; //创建一个字体来使用和编码格式 BaseFont baseFont = BaseFont.CreateFont("C:\\Windows\\F ...

  8. 【Web】java异常处理

    J2EE中一般对异常状况的处理都可以用两种情况对其进行相应处理. 1. 通常情况下,一般异常处理可以选择用throw.throws从底层一直往上面抛,直到抛到Action,让其将异常显示在页面上面进行 ...

  9. linux下安装greenplum

    1. 下载 Greenplum Database 源代码 $ git clone https://github.com/greenplum-db/gpdb 2. 安装依赖库 Greenplum Dat ...

  10. <转> 30 个有关 Python 的小技巧

    目录[+] 1.1 拆箱 1.2 拆箱变量交换 1.3 扩展拆箱(只兼容python3) 1.4 负数索引 1.5 切割列表 1.6 负数索引切割列表 1.7指定步长切割列表 1.8 负数步长切割列表 ...