Apache Flink 数据流编程模型

抽象等级(Levels of Abstraction)

Flink提供不同级别的抽象来开发流/批处理应用程序。

Statefule Stream Processing: 是最低级别(底层)的抽象,只提供有状态的流。它通过ProcessFunction嵌入到DataStream API之中。它使得用户可以自由处理来源于一个或者多个流的事件

DataStream/DataSet API: 在我们的实际工作中,大多数的应用程序是不需要上文所描述的低级别(底层)抽象,而是相对于诸如DataStream API(有界/无界流)和DataSet API(有界数据集)的Core API进行编程。这些API提供了用于数据处理的通用模块,如各种指定的transformations, joins, aggregations, windows, state等。在API中,这些处理的数据类型都是一个具体的实体类(class)。

底层的Process Function与DataStream API集成在一起,可以仅对一些操作进行底层抽象。

Table API: 是围绕着table的申明性DSL,可以被动态的改变(当其表示流时)。Table API遵循(扩展)关系模型:表有一个模式链接(类似与在关系数据库中的表),API也提供了一些类似的操作:select, project, join, group-by, aggregate等。Table API程序申明定义了怎么做是规范的,而不是明确指定应该是什么样子的。虽然Table API可以通过各种类型的用户定义的函数进行扩展,但它比Core API表达的更少,但使用起来更简洁(少写代码)。另外,Table API程序也会通过一个优化器,在执行之前应用优化规则。

可以在表和DataStream / DataSet之间进行无缝转换,允许程序混合使用Table API和DataStream 和DataSet API。

Flink提供的最高级抽象是SQL。 这种抽象在语义和表现力方面与Table API类似,但是将程序表示为SQL查询表达式。在SQL抽象与Table API紧密地相互作用,另外,SQL查询可以在Table API中定义的表上执行。

程序和数据流(Programs and Dataflows)

Flink可以说是由流(streams)和转换(transformations)为基础构建的(请注意,Flink的DataSet API中使用的数据集也是内部的流 )。从概念上讲,流是数据记录(可能是永无止境的)流,而转换是将一个或多个流作为输入,并产生一个或多个输出流。

执行时,Flink程序被映射到由流和转换运算符组成的流式数据流。每个数据从一个或多个源(sources)开始,并在一个或者多个接收器(sinks)中结束。数据流类似于一个任意有向无环图(DAG)。尽管通过迭代构造允许特殊形式的循环,但是为了简单起见,我们姑且先忽视这种情况。

程序中的转换与数据流中的操作符通常是一一对应的。然而,有时候,一个转换可能由多个转换操作符组成。

信号源(sources)和接收器(sinks)记录在流式连接器批量连接器文档中。DataStream运算符DataSet转换中记录了转换。

并行数据流(Parallel Dataflows)

Flink中的程序本质上是并行和分布的。在执行过程中,一个流有一个或者多个流分区,每个运算符有一个或者多个子任务。操作符子任务彼此独立,并且在不同的线程中执行,并且可能在不同的机器或容器上执行。

操作符子任务的数量是该特定操作符的并行度。流的并行性总是由生产它的操作符决定。同一个程序的不同运算符可能有不同的并行级别。

流可以以一对一(One-to-one)或者重新分配(Redistributing)的模式在两个操作符之间传输:

One-to-one: 保留了元素的分区和顺序,如上图中source —>map。这意味着map运算符的subtask[1]将按照源运算符的subtask[1]所产生顺序相同。

Redistributing: 如上图所示,map和keyBy/window之间,以及keyBy/window和Sink之间重新分配流,将会改变流的分区。每个操作符子任务根据所选的转换将数据发送到不同的目标子任务。比如 keyBy()(其通过哈希重新分区),broadcast(), or rebalance() (其随机重新分区)。在重新分配 交换中,元素之间的排序只保存在每对发送和接收的子任务中(例如map() 的subtask[1] 和 keyBy /window的subtask [2])。所以在这个例子里,每个关键字中的排序都被保留下来,但是并行性确实造成了不同关键字汇总结果后顺序的非确定性。

有关配置和控制并行的细节可以在并行执行的文档中找到。

窗口(Windows)

聚合事件(如:sum,count,etc)在流上的工作方式与批处理中的不同。例如,我们不能够去统计流中的所有元素,因为流一般是无限的(无界的)。因而,流中的一些aggregate操作,是由Windows控制的,例如:计算过去五分钟或者最后100个元素的总和。

Windows可以是由时间驱动的(例如,每30秒)或者数据驱动(例如每100个元素)。这可以用来区分不同类型的Windows,例如:tumbling windows (no overlap), sliding windows (with overlap), and session windows (punctuated by a gap of inactivity).

更多的窗口示例可以在这篇博客文章中找到。更多细节在窗口文档

时间(Time)

当我们在流式编程中谈及时间时,可以参考不同的时间概念:

Event Time, 是事件创建的时间,通常用时间戳表示。Flink通过时间戳分配器来访问事件时间戳。

Ingestion time, 是事件进入Flink的时间,在源操作中每个记录都会获得源的当前时间作为时间戳,后续基于时间的操作(如: time window)会依赖这个时间戳

Processing Time, 是指each operator 执行程序时对应的物理机的系统时间

有关如何处理时间的更多细节,请参阅event time 文档

有状态的操作(Stateful Operations)

尽管数据流中很多操作看起来像一个单独的事件,但是一些操作会跨越几个事件记下相关的的信息(比如像window operators)。这种操作被称为有状态的(stateful)。

这种有状态的操作,被保存在一种key/value的存储结构之中。状态与有状态操作符读取的流严格分区和分配。只有在keyed()函数之后才能访问key/value状态。并且仅限于与当前事件的键相关的值。流和状态的keys的匹配保证了所有状态更新都是本地操作,保证了一致性,所以不需要事务的开销。这种匹配还允许flink重新分配状态,并公开的调整分区。

有关更多信息,请参阅有关状态的文档

检查点容错(Checkpoints for Fault Tolerance)

Flink使用流重播(stream replay)检查点(checkpointing) 的组合来实现容错。检查点与每个输入流中的特定点以及每个操作元的相应状态有关。数据流可以从检查点恢复,同时保持一致性(exactly-once processing语义),方法是恢复operators 的状态并从检查点重放事件。

检查点间隔是在执行恢复时间(需要被重放的事件的数量)的情况下折衷的容错开销手段。

容错内部的描述提供了有关Flink如何管理检查点和相关主题的更多信息。有关启用和配置检查点的详细信息位于检查点API文档中。

批处理流(Batch on Streaming)

Flink执行批处理程序作为流程序的特殊情况,它是有限的(元素是有限的)。ADataSet 在内部视为数据流。因此,上述概念同样适用于批处理程序,就像适用于流式处理程序一样,但有一点例外:

  • 批处理程序的容错不使用检查点。通过完全重放流来恢复。这是可能的,因为输入是有限的。这将成本更多推向recovery,但是使常规地处理更便宜,因为它避免了检查点。
  • DataSet API中的有状态操作使用简化的内存/外核数据结构,而不是键/值索引。
  • DataSet API引入了特殊的同步(超级)iterations,这只能在有界的流上进行。有关详细信息,请查看iterations文档

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Json技术使用代码示例

    JSON(JavaScript Object Notation)一种简单的数据格式,比xml更轻巧。JSON是JavaScript原生格式,这意味着...

    chaplinthink
  • 了解下Scala隐式转换与柯理化

    之前有看过kafka源码,有很多implict声明的方法,当时看的一头雾水,今天趁着空闲,了解下scala 的隐式转换和柯理化相关语法知识.

    chaplinthink
  • Spark Web UI 监控详解

    我们有2个节点,每个节点是一个worker,每个worker上启动一个Executor,其中Driver也跑在master上。每个Executor可使用的核数为...

    chaplinthink
  • 想成为技术大咖?那就从API的使用开始吧

    近几年,API经济纷纷崛起,无论是国外还是国内,众多厂商积极开放API。从2011年开始,数据通过API开发出来已成为一种趋势,与此同时它也逐渐发成为企业的核心...

    BestSDK
  • API网关在API安全性中的作用

    从单一应用程序切换到微服务时,客户端的行为不能与客户端具有该应用程序的一个入口点的行为相同。简单来说就是微服务上的某一部分功能与单独实现该应用程序时存在不同。

    架构师修炼
  • 《软件测试52讲》读书笔记 —— API测试怎么做

    文章中还介绍了测试工具,比如cURL、postman,单API如何测试;但这些都是偏基础的东西,且网上教程各式各样,就不再赘述了;这里主要讲的就是关于复杂场景的...

    小菠萝测试笔记
  • API安全发展趋势与防护方案

    近些年,API安全在安全领域越来越多的被业界和学术界提及和关注。OWASP在2019年将API安全列为未来最受关注的十大安全问题。事实上随着应用程序驱动的普及,...

    绿盟科技研究通讯
  • 【物联网安全】通过API管理最小化物联网安全失误

    物联网的采用在不同行业中迅速增长并不是秘密。在我的最后一篇文章中,我讨论了基于blockchain的IoT安全策略,这是一个不断发展的主题,我发现重要,经常被忽...

    首席架构师智库
  • 没有被了解的API?一个老码农眼中的API世界

    即便做了20多年的软件开发,仍然发现自己经常会低估完成一个特定的编程任务所需要的时间。有时,错误的时间表是由于自己的能力不足造成的: 当深入研究一个问题时,会发...

    半吊子全栈工匠
  • 前端基础-浏览器API

    API(Application Programming Interface,应用程序编程接口)是一些预先定义的函数,目的是提供应用程序与开发人员基于某软件或硬件...

    cwl_java

扫码关注云+社区

领取腾讯云代金券