Flink 编程模型
抽象层次

最低级的抽象接口是状态化的数据流接口(stateful streaming)。这个接口是通过 ProcessFunction 集成到 DataStream API 中的。该接口允许用户自由的处理来自一个或多个流中的事件,并使用一致的容错状态。另外,用户也可以通过注册 event time 和 processing time 处理回调函数的方法来实现复杂的计算。
大部分程序通常会使用以 DataStream API(有界/无界数据流)、DataSet API(有界数据集)为代表的 Core APIs,并不会使用低级抽象接口。这些API为数据处理提供了大量的通用模块(common building block),包括用户定义的各种各样的变换(transformations)、连接(joins)、聚合(aggregations)、窗口(windows)、状态(state)等等。DataStream API 集成了 low level 处理函数,使得对一些特定的操作提供更低层次的抽象。此外,DataSet API 也为有界数据集提供了一些补充的编程原语,例如循环(loops)、迭代(iterations)等。
Table API 是一种以数据表为核心地声明式 DSL,能够动态地修改表(表示流时)。Table API 的是一种(扩展的)关系型模型:每个都有一个 schema(类似于关系型数据库中的表结构),API也提供以下操作: select,project,join,group by,aggregate等。Table API 程序定义的是应该执行什么样的逻辑操作,而不是直接准确地指定程序代码运行的具体步骤。尽管 Table API 可以通过各式各样的自定义函数进行扩展,但是它在表达能力上仍然比不上 Core APIs,不过在使用上更简练(可以减少很多代码)。此外,Table API 程序在运行之前也会使用一个优化器对程序进行优化。用户可以在 tables 与 DataStream/DataSet 之间进行无缝切换,程序也可以混合使用 Table API 和 DataStream/DataSet APIs。
Flink 提供的最高级接口是 SQL。这个层次的抽象接口和 Table API 非常相似,包括语法和接口的表现能力,唯一的区别是通过 SQL 查询语言实现程序。SQL 抽象接口和 Table API 的交互非常紧密,而且 SQL 查询也可以在 Table API 中定义的表上执行。
程序与数据流(Dataflow)
Flink 程序的基础构建单元是流(streams) 与转换(transformations)。DataSet API 中使用的数据集也是一种流。数据流(stream)就是一组永远不会停止的数据记录流,而转换(transformation)是将一个或多个流作为输入,并生成一个或多个输出流的操作。
执行时,Flink程序映射到 streaming dataflows,由流(streams)和转换操作(transformation operators)组成。每个 dataflow 从一个或多个源(source)开始,在一个或多个接收器(sink)中结束。dataflow 类似于有向无环图(DAG)。虽然可以通过迭代构造器生成某些特殊形式的环,但为了简化说明,大部分情况下我们不考虑这种结构。
通常情况下程序中的 transformation 和数据流图(dataflow)中的 operator 是一一对应的。不过有的时候也会出现一个 transformation 由多个operators 组成的情况。

并发数据流
Flink 程序是分布式、并发执行的。运行过程中,一个数据流可能会有一个或多个流分区(stream partitions),而一个 operator 也可能会有一个或多个运算子任务(operator subtasks)。运算子任务之间都是相互独立的,在不同的线程中运行的,可能在不同的机器或容器(container)上执行。运算子任务的数量由指定运算符(operator)的并发数确定。数据流的并发数就是它所生成的运算符的并发数。同一程序中不同的运算符可以有不同等级的并发量。

数据流可以使用一对一的模式(one-to-one pattern)在两个运算符之间传输,也可以使用重分发模式(redistributing pattern):
一对一模式,例如上图中 Source 和 map() 运算符之间的数据流。数据流中元素的分组和顺序会保持不变。也就是说,map() 运算符的子任务[1]所看见的元素与 Source 运算符的子任务[1]所生成的元素的顺序完全一致。
重分发模式,例如上图中 map() 和 keyBy/window 运算符之间的数据流,以及 keyby/window 和 Sink 运算符之间的数据流。数据流所在的分区会改变。每个运算子任务会发送数据到不同的下游运算子任务(根据不同的运算转换)。例如 keyby() 运算符(通过对 key 进行哈希计算来重分区),boradcast() 和 rebalance()(随机重分区)就是重分发模式的例子。在此模式下,元素间的顺序只保留在每对发送-接收子任务中(例如 map() [1]和 keyBy/window[2])。尽管在子任务之间每个 key 的顺序都是确定的,但是由于程序的并发引入了不确定性,最终到达 Sink 的元素顺序就不能保证与一开始的元素顺序完全一致。
窗口
聚合事件(counts、sums 等)在流和批处理过程的工作模式完全不同。例如,计算数据流中的所有元素的个数是无法实现的,因为流在概念上是无限无边界的。因此,数据流的聚合操作都是由窗口(window)限定了范围来计算的,例如,“计算过去五分钟的元素个数”,“对最后100个元素求和”等。窗口可以时间驱动(例如以30秒为单位)或者数据驱动(例如以100个元素为单位)。有多种不同类型的窗口,例如,数据不重叠的滚动窗口(tumbling window)、数据重叠的滑动窗口(sliding window),以及以非活动状态为间隔的会话窗口(session window)。

时间
流式计算程序中的时间概念(例如在定义窗口时经常会用到的时间)有以下几种含义:
事件时间(Event Time),是指事件发生的时间,通常在事件的内容中由时间戳表示。
接入时间(Ingestion Time),是指事件在 source 运算符中进入 Flink 数据流的时间。
处理时间(Processing Time),是指运算符在执行时间类操作时的本地时间。

有状态操作
虽然数据流中的许多操作一次只查看一个单独的事件,但有些操作会记录多个事件之间的信息(例如窗口运算符)。这种操作就称为有状态的操作(stateful)。
有状态操作的状态可以理解成是以键值对(key/value)形式存储。这个状态的分区和分布是和数据流严格绑定在一起的。因此,在 keyBy() 函数执行之后,只能在带键的数据流中访问 key/value 状态,而且也只能获取与当前事件的主键相对应的值。数据流的键和状态的严格对应,确保了所有状态更新都是本地操作,同时也保证了事务的一致性。这种方式也使得Flink可以透明地重分发状态,调整数据流分区。

容错检查点
Flink 通过流重放(stream replay)和检查点机制(checkpoint)结合的方式实现了容错能力。检查点与每个输入流中的特定一点以及每个操作的相应状态相关。数据流可以从检查点恢复来保持一致性(exactly-once的语义),通过恢复操作的状态和从检查点开始重放事件。检查点间隔是对程序的容错能力与恢复时间(需要重发的事件数量)的平衡手段。
批处理操作
Flink 将批处理看作一种特殊的流处理,只是数据流有界的特例。DataSet 也被看作一种流数据。流式计算程序中的很多概念也能应用到批处理程序中,除了以下几处不同:
批处理程序的容错机制不使用检查点机制。而是通过完全重发所有数据流实现的,因为输入数据是有界的。这样,恢复过程中的开销可能更大一些,但是由于没有了检查点,正常处理过程的开销反而更小。
DataSet API 中的有状态操作没有使用键/值(key/value)索引存储,而是使用了简化的 in-memory/out-of-core 数据结构,
DataSet API 引入了特殊的同步(基于 superstep)迭代接口,该接口仅能用于有界数据流。
https://ci.apache.org/projects/flink/flink-docs-release-1.6/concepts/programming-model.html
转载:https://www.jianshu.com/p/79275f1a6057
Flink 编程模型的更多相关文章
- 第03讲:Flink 的编程模型与其他框架比较
Flink系列文章 第01讲:Flink 的应用场景和架构模型 第02讲:Flink 入门程序 WordCount 和 SQL 实现 第03讲:Flink 的编程模型与其他框架比较 本课时我们主要介绍 ...
- [Note] Apache Flink 的数据流编程模型
Apache Flink 的数据流编程模型 抽象层次 Flink 为开发流式应用和批式应用设计了不同的抽象层次 状态化的流 抽象层次的最底层是状态化的流,它通过 ProcessFunction 嵌入到 ...
- flink原理介绍-数据流编程模型v1.4
数据流编程模型 抽象级别 程序和数据流 并行数据流 窗口 时间 有状态操作 检查点(checkpoint)容错 批量流处理 下一步 抽象级别 flink针对 流式/批处理 应用提供了不同的抽象级别. ...
- Flink入门(四)——编程模型
flink是一款开源的大数据流式处理框架,他可以同时批处理和流处理,具有容错性.高吞吐.低延迟等优势,本文简述flink的编程模型. 数据集类型: 无穷数据集:无穷的持续集成的数据集合 有界数据集:有 ...
- DataFlow编程模型与Spark Structured streaming
流式(streaming)和批量( batch):流式数据,实际上更准确的说法应该是unbounded data(processing),也就是无边界的连续的数据的处理:对应的批量计算,更准确的说法是 ...
- JS魔法堂:深究JS异步编程模型
前言 上周5在公司作了关于JS异步编程模型的技术分享,可能是内容太干的缘故吧,最后从大家的表情看出"这条粉肠到底在说啥?"的结果:(下面是PPT的讲义,具体的PPT和示例代码在h ...
- 多线程之异步编程: 经典和最新的异步编程模型,async与await
经典的异步编程模型(IAsyncResult) 最新的异步编程模型(async 和 await) 将 IAsyncInfo 转换成 Task 将 Task 转换成 IAsyncInfo 示例1.使用经 ...
- 多线程之异步编程: 经典和最新的异步编程模型, IAsyncInfo 与 Task 相互转换
经典的异步编程模型(IAsyncResult) 最新的异步编程模型(async 和 await) 将 IAsyncInfo 转换成 Task 将 Task 转换成 IAsyncInfo 示例1.使用经 ...
- jQuery插件编写及链式编程模型小结
JQuery极大的提高了我们编写JavaScript的效率,让我们可以愉快的编写代码,做出各种特效.大多数情况下,我们都是使用别人开发的JQuery插件,今天我们就来看看如何把我们常用的功能做出JQu ...
随机推荐
- Insmod模块加载过程分析
一.背景 a) 在进行JZ2440的一个小demo开发的时候,使用自己编译的内核(3.4.2)及lcd模块进行加载时,insmod会提示加载失败因为内核版本不匹配(提示当前内核版本为空),并且显示模块 ...
- php下载
生成迅雷下载链接 $url = "http://www.xxx.com/xxx/test.jpg"; echo "thunder://".base64_enco ...
- MySQL高级学习笔记(六):MySql锁机制
文章目录 概述 定义 生活购物 锁的分类 从对数据操作的类型(读\写)分 从对数据操作的粒度分 三锁 表锁(偏读) 特点 案例分析 建表SQL 加读锁 加写锁 结论 如何分析表锁定 行锁(偏写) 特点 ...
- shell编程:命令替换的运用
命令替换,有两种方式 方式一:`command` 方式二:$(command) user.sh 查找系统中所有的用户,并且输出 #!/bin/bash nginx=`netstat -tnlp | | ...
- php &引用符的注意情况
- Spring入门之生命周期
好几日没有读东西了,今天本来要读mybatis原理部分,但是看到作者讲,只是学会用不用学那么深,遂直接开干spring,工作中一直用springboot,框架都是领导搭好的,每天的任务就是增删改查,挺 ...
- 将rdlc报表作为资源嵌套使用
原文:将rdlc报表作为资源嵌套使用 如果我们准备在Windows Forms里面使用rdlc报表,那么会遇到一个问题:rdlc报表到底要不要作为附属文件的方式随程序发布? 这样做的优点是:报表可以后 ...
- ArcGis基础——设置图层可选状态
在ArcMap的图层列表上右键,可以设置“仅本图层可选”. 那么,如何设置回多个或者全部图层可选状态呢? 1.在ArcMap的菜单栏找到 自定义——自定义模式——选择——设置可选图层. 2.将“设置可 ...
- 8、服务发现&服务消费者Feign
spring cloud的Netflix中提供了两个组件实现软负载均衡调用,分别是Ribbon和Feign.上一篇和大家一起学习了Ribbon. Ribbon :Spring Cloud Ribbon ...
- vue 计算属性的setter getter
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...