Flink-Concepts-Programming Model

多级抽象


flink为开发streaming/batch 应用提供了不同层级的抽象。


  • 最底层的抽象提供了有状态的流(stateful streaming)。它通过Process Function内置在DataStream API中。它允许用户自由的处理一个或多个流中的数据,并且使用统一的故障容忍的状态(state)。除此之外,用户可以注册事件时间(event time)的回调与处理时间(processing time)的回调函数,允许程序实现更精细化的操作。
  • 在实践中,大多数应用不会用到上面描述的等层级的抽象api,而是使用 Core APIS,如 DataStream API(有界/无界流)与DataSet API(有界流)。链式API提供了构造数据流的常用构造块,如多种用户可指定的transformation,joins,aggregations,windows,state等。被这些api所处理的数据类型,便是使用相应编程语言写api的对应语言的类(理解:如使用java写map这个api,那么map所处理的入参,便是一个java类)。
    底层的 Process Function 集成在 DataStream API中,可以使得仅在某个有需要的操作符中使用更底层的api。
    DataSet API为有界数据提供了额外的基础操作,如loops/iterations。,
  • Tabel API是一个关于表(table)的领域特定语言(DSL),这些表可能是一个动态变化的表(如在流场景中)。Table API遵循了(也扩展了)关系型模型:每张表都有schema(和关系型数据库类似),并且API提供了类似的操作符,如:select,project,join,group-by,aggregate等。使用Table API的应用重点关注应该使用哪一个操作符,而不是关注如何实现作这个操作。尽管Table API可以使用很多的UDF(自定义函数),但是与Core API比起来表达能力还是差了许多,但是使用起来更简洁(更少的代码)。除此之外,Table API的应用会通过一个优化器,以在真正执行前,对程序进行优化。
    使用者可以无缝的在Table 和 DataStream/DataSet 中转化,这样的特定是的程序可以使得应用将 Tabel API , DataStream/DataSet API 混合起来使用。
  • Flink提供的最高等级的抽象是SQL。这层抽象和Table API的应用场景与表达能力类似,但是不同的是其使用SQL来编写程序。SQL与Table API紧密的交互,并且SQL可以查询使用Table API定义的表。

程序与数据流

Flink程序中的基础构造块是streams与transformations。(注意的是使用DataSet API构造的数据集,在flink内部也被看做是一个流)stream的概念是指源源不断的数据(可能不会中断),transformation是指一个操作,它将一个或多个流作为输入,并且将一个或多个流作为输出结果。

当执行时,Flink应用会映射为streaming dataflows(数据流),它有streams以及转化操作符组成。每一个数据流都由一个或多个source开始,并以一个或多个sink结束。数据流一般来说是一个DAG(有向无环图),尽管某些特殊的“环”是允许的如iteration,但对大部分我们将要讨论的情况,我们暂时忽略这种特殊情况。


一般来说,数据流中的操作符与程序中的transformation是一一对应的。但是有时候,一个transformation可能由多个转化操作符组成。

并发数据流


Flink程序本就是并行分布式的计算。在执行时,一个流有一个或多个分区(stream partitions),每个操作符也是有一个或多个operator subtasks(操作符子任务)。 每个operator subtask之间都是独立的,并且在不同的线程甚至是不同的容器/机器上执行。
某个operator的subtask的数量就是这个operator的并发度(parallelism)。一个流的并发度总是产生该流的操作符的并发度。同一个程序的不同的操作符可能拥有不同的并发度。


流中的数据发送到下一个操作符有两种模式:一对一(转发)模式,重分配(redistributing) 模式

  • 一对一:一个流(如在上图的source和map操作符之间)保留了数据所在的分区与顺序。这意味着map操作符的subtask[1]中所接收到的数据与source操作符的subtask[1]的数据完全相同且顺序也相同。
  • 重分配模式:一个流(如上图map和keyBy/window之间,或者keyBy/window与sink之间)的分区被改变。每个操作符的subtask会根据所选的转化逻辑,将数据发送到不同的许多subtask中。如keyBy()会根据key的hash值来选择该数据的分区,然后发送;broadcast()(广播,将数据发送到所有下游分区);rebalance()(随机重分配)。这种情况下,元素间的顺序,仅在发送与接收的subtask间保持(如,mapd的subtask[1]与keyBy/window的subtask[2])。这个例子中,keyBy/window中的所有key的元素顺序都保留了,但这并不说明并发度不会有其他问题,考虑到keyBy/window最后每个key聚合的结果发送到sink节点的顺序不确定,这说明并发度也会带来不确定性。

windos


在流上对时间进行聚合(如,计数,求和)与批处理是很不一样的。例如,不可能统计流中的所有元素,因为数据流式无限的。因此,在流上的统计都会指定window,例如“统计最新5分钟的数据”或者“对最新的100个元素求和”。
window可以是时间驱动(time driven)(如:每30秒)或者数据驱动(data driven)(如:每100个数据)。有这么几种类型的window:tumbling window滚动窗口(窗口间没有重叠),sliding window滑动窗口(窗口间有重叠),session window(由一段不活跃时间段来分隔两个window)


时间


当在流程序中说道时间时(如定义一个window),有几种不同概念的时间:

  • event time:代表事件产生的时间。它通常是指事件数据中的时间戳。Flink中使用 timestamp assigner 来指定数据中的时间戳。
  • ingestion time:数据通过source操作符进入flink数据流的时间。
  • processing time:操作符处理数据时的所在机器的机器本地时间。


    image.png

有状态的操作符


尽管有些数据流中的操作符看起来就是在同一时间仅对一个数据做处理(如数据解析),但是许多操作符还能够根据多个数据记住某些信息(如window操作符)。这种操作符称为有状态的操作符。
这些操作符的状态(state)是由内置的key/value来存储维持。某个state会随同它所在的操作符所处理的流一起被分区与分配。因此,只有通过keyBy操作符产生keyedStream后,才可以在keyedStream中访问key/value的state,并且访问的state的key被当前流中的数据的key所限制(即不能访问不再这个keyedStream分区中的key的value)。这样的限制(流中的key与state中的key要“对齐”)保证了state的更新都是本地操作,保证了state的一致性,减少了更新state且保持一致性导致的事务开销。这样的对齐也实现了调整流的分区时,state也会显然的同时被调整。


image.png

检查点与故障容忍


Flink通过结合流回放(stream reply)与检查点(checkpointing)实现了故障容忍。检查点代表某个时刻,流上所有操作符的状态。通过存储操作符的状态与回放从检查点开始的数据,流应用可以从检查点处重启且保持一致性(精确一次处理的语义 exactly-once processing semantics)。

检查点间隔代表着一种权衡:执行时管理故障容忍的开销 与 故障恢复时的恢复时间。

Batch on Streaming


Flink将batch程序当做流来处理,一个有界的流(有限的元素数量)。在内部,DataSet会被看做是一个数据流。上面的概念放到批处理上与在流处理上是一样的,除了一下几点:

  • 批处理的故障容忍不使用检查点。批处理的故障恢复通过全部重新回放流数据来实现。因为输入是有限的,因此这样做是可以实现的。这样做在恢复时会有更多的开销,但是使得内部的数据处理更简单,因为内部不需要进行检查点的操作。
  • 有状态的操作符的状态使用的是简单的 内存/out-of-core 数据结构,而不是key/value
  • DataSet API 引入了特殊的同步的仅可在有界流中使用的迭代iteration
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,185评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,445评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,684评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,564评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,681评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,874评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,025评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,761评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,217评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,545评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,694评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,351评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,988评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,778评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,007评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,427评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,580评论 2 349

推荐阅读更多精彩内容

  • Apache Flink是一个面向分布式数据流处理和批量数据处理的开源计算平台,它能够基于同一个Flink运行时,...
    康小为6840阅读 1,191评论 0 7
  • 原文地址 抽象层级 Flink提供不同的抽象层级来开发流/批处理应用。 最低层次的抽象只提供有状态的流。它可以通过...
    小C菜鸟阅读 1,332评论 0 0
  • 本文是先介绍 Flink,再说 Flink的过去和现在 一、Flink介绍 Flink是一款分布式的计算引擎,它可...
    生活的探路者阅读 1,274评论 0 22
  • Flink总结 Flink简介 Apache Flink作为一款高吞吐量、低延迟的针对流数据和批数据的分布式实时处...
    bigdata_er阅读 10,591评论 0 10
  • 介绍 概述 Apache Flink是一个面向数据流处理和批量数据处理的可分布式的开源计算框架,它基于同一个Fli...
    stephen_k阅读 50,794评论 0 22