解析Flink内核原理与实现核心抽象

目录
  • 一、环境对象
    • 1.1 执行环境
      • StreamExecutionEnvironment
      • LocalStreamEnvironment
      • RemoteStreamEnvironment
      • StreamContextEnvironment
      • StreamPlanEnvironment
      • ScalaShellStreamEnvironment
    • 1.2 运行时环境
      • RuntimeEnvironment
      • SavepointEnvironment
    • 1.3 运行时上下文
      • StreamingRuntimeContext:
      • DistributedRuntimeUDFContext:
      • RuntimeUDFContext:
      • SavepointRuntimeContext:
      • CepRuntimeContext:
      • StreamRecord
      • LatencyMarker
      • Watermark
      • StreamStatus
      • Transformation有两大类:
      • Tranformation包含了Flink的运行时关键参数:
  • 二、数据流元素
  • 三、数据转换
    • 3.1 物理Transformation SourceTransformation
      • SinkTransformation
      • OneInputTransformation
      • TwoInputTransformation
    • 3.2 虚拟Transformation SideOutputTransformation
      • SplitTransformation
      • SelectTransformation
      • PartitionTransformation
      • UnionTransformation
      • FeedbackTransformation
      • CoFeedbackTransformation
  • 四、算子行为
    • 4.1 生命周期管理
    • 4.2 异步算子
      • 1)顺序输出
      • 2)无序输出
  • 五、处理函数
    • 5.1 双流Join 即时Join
    • 5.2延迟双流Join
      • StreamParitioner
      • 自定义分区
      • ForwardParitioner
      • ShufflePartitioner
      • ReblancePartitioner
      • RescalingPartitioner
      • BroadcastPartitioner
      • KeyGroupStreamPartitioner
  • 六、数据分区
  • 七、分布式ID

Flink中设计了用户自定义函数体系(User Defined Function,UDF),开发人员实现业务逻辑就是开发UDF。

一、环境对象

StreamExecutionEnvironment是Flink应用开发时的概念,表示流计算作业的执行环境,是作业开发的入口、数据源接口、生成和转换DataStream的接口、数据Sink的接口、作业配置接口、作业启动执行的入口。

Environment是运行时作业级别的概念,从StreamExecutionEnvironment中的配置信息衍生而来。进入到Flink作业执行的时刻,作业需要的是相关的配置信息,如作业的名称、并行度、作业编号JobID、监控的Metric、容错的配置信息、IO等,用StreamExecutionRuntime对象就不适合了,很多API是不需要的,所以在Flink中抽象出了Environment作为运行时刻的上下文信息。

RuntimeContext是运行时Task实例级别的概念。Environment本身仍然是比较粗粒度作业级别的配置,对于每一个Task而言,其本身有更细节的配置信息,所以Flink又抽象了RuntimeContext,每一个Task实例有自己的RuntimeContext。

环境对象关系如下:

1.1 执行环境

StreamExecutionEnvironment

Flink流计算应用的执行环境,是Flink作业开发和启动执行的入口

开发者对StreamExecutionEnvironment的实现是无感知的。

LocalStreamEnvironment

本地执行环境,在单个JVM中使用多线程模拟Flink集群。

其基本的工作流程如下:

1) 执行Flink作业的Main函数生成Streamgraph,转化为JobGraph。

2) 设置任务运行的配置信息。

3) 根据配置信息启动对应的LocalFlinkMiniCluster。

4) 根据配置信息和miniCluster生成对应的MiniClusterClient。

5) 通过MiniClusterClient提交JobGraph 到MiniCluster。

RemoteStreamEnvironment

在大规模数据中心中部署的Flink生产集群的执行环境。

当将作业发布到Flink集群的时候,使用RemoteStreamEnvironment。

其基本的工作流程如下:

1) 执行Flink作业的Main函数生成Streamgraph,转化为JobGraph。

2) 设置任务运行的配置信息。

3) 提交JobGraph到远程的Flink集群。

StreamContextEnvironment

在Cli命令行或者单元测试时候会被使用,执行步骤同上。

StreamPlanEnvironment

在Flink Web UI管理界面中可视化展现Job的时候,专门用来生成执行计划(实际上就是StreamGraph)

ScalaShellStreamEnvironment

这是Scala Shell执行环境,可以在命令行中交互式开发Flink作业。

其基本工作流程如下:

  • 校验部署模式,目前Scala Shell仅支持attached模式。
  • 上传每个作业需要的Jar文件。

其余步骤与RemoteStreamEnvironment类似。

1.2 运行时环境

RuntimeEnvironment

在Task开始执行时进行初始化,把Task运行相关的信息都封装到该对象中,其中不光包含了配置信息,运行时的各种服务也会被包装到其中。

SavepointEnvironment

SavepointEnvironment是Environment的最小化实现,在状态处理器的API中使用。

1.3 运行时上下文

RuntimeContext是Function运行时的上下文,封装了Function运行时可能需要的所有信息,让Function在运行时能够获取到作业级别的信息,如并行度相关信息、Task名称、执行配置信息(ExecutionConfig)、State等。

Function的每个实例都有一个RuntimeContext对象,在RichFunction中通过getRunctionContext()可以访问该对象。

RuntimeContext的类体系图如下:

StreamingRuntimeContext:

在流计算UDF中使用的上下文,用来访问作业信息、状态等。

DistributedRuntimeUDFContext:

由运行时UDF所在的批处理算子创建,在DataSet批处理中使用。

RuntimeUDFContext:

在批处理应用的UDF中使用。

SavepointRuntimeContext:

支持对检查点和保存点进行操作,包括读取、变更、写入等。

CepRuntimeContext:

CEP复杂事件处理中使用的上下文。

二、数据流元素

数据流元素在Flink中叫做StreamElement

  • 有数据记录StreamRecord,
  • 延迟标记LatencyMarker、Watermark、
  • 流状态标记StreamStatus这四种。

在执行层面,4种数据流元素都被序列化成二进制数据,形成混合的数据流,在算子中将混合数据流中的数据流元素反序列化出来。

StreamRecord

StreamRecord表示数据流中的一条记录(或者叫做一个事件),也叫数据记录。

包含以下内容:

1)数据的值本身

2)时间戳(可选)

LatencyMarker

用来近似评估延迟,LatencyMarker在Source中创建,并向下游发送,绕过业务处理逻辑,在Sink节点中使用LatencyMarker估计数据在整个DAG图中的流转花费的时间。

LatencyMarker包含信息如下:

1)周期性的在数据源算子中创造出来的时间戳。

2)算子编号

3)数据源算子所在的Task编号

Watermark

是一个时间戳,用来告诉算子所有时间早于等于Watermark的事件或记录都已经达到,不会再有比Watermark更早的记录。

StreamStatus

用来通知Task是否会继续接收到上游的记录或者Watermark。在数据源算子中生成,向下游沿着DataFlow传递。

有两种表示状态:

1)空闲状态(IDLE)

2)活动状态(ACTIVE)

三、数据转换

数据转换在Flink中叫做Transformation,是衔接DataStream Api和Flink内核的逻辑结构。

Transformation有两大类:

1)物理Transformation: 会转换成算子,继承了PhysicalTransformation。

2)虚拟Transformation: 不会转换成具体算子。

Tranformation包含了Flink的运行时关键参数:

1)name:转换器名称,主要用于可视化。

2)uid:用户指定的uid,该uid的主要目的是在job重启时再次分配跟之前相同的uid,可以持久保存状态。

3)bufferTimeout:buffer超时时间。

4)parallelism:并行度。

5)id:跟属性uid无关,生成方式是基于一个静态累加器。

6)outputType:输出类型,用来进行序列化数据。

7)slotSharingGroup:给当前的Transformation设置Slot共享组。

3.1 物理Transformation SourceTransformation

从数据源读取数据的Transformation,是Flink作业的起点。

只有下游Transformation,没有上游输入。

SinkTransformation

将数据写到外部存储的Transformation,是Flink作业的终点。

OneInputTransformation

单流输入的Transformation(只接收一个输入流),跟上面的SinkTransformation构造器类似,同样需要input和operator参数。

TwoInputTransformation

双输入的Transformation(接收两种流作为输入),分别叫做第一输入和第二输入。

3.2 虚拟Transformation SideOutputTransformation

在旁路输出中转换而来,表示上游Transformation的一个分流。

每个sideoutput通过OutputTag标识。

SplitTransformation

用来按条件切分数据流,该转换用于将一个流拆分成多个流。

SelectTransformation

与SplitTransformation配合使用,用来在下游选择SplitTransformation切分的数据流。

PartitionTransformation

该转换器用于改变输入元素的分区,其名称为Partition。工作时除了提供一个StreamTransformation作为输入外,还需要提供一个StreamPartitionor的实例来进行分区。

UnionTransformation

合并转换器,该转换器用于将多个输入StreamTransformation进行合并,因此该转换器接收StreamTransformation的集合。Union要求上游输入的数据的结构必须是完全相同的。

FeedbackTransformation

表示FlinkDAG中的一个反馈点。简单来说,就是把符合条件的数据发回上游Transformation处理,一个反馈点可以连接一个或多个上游的Transformation,这些连接关系叫反馈边。符合反馈条件并交给上游的Transformation的数据流叫做反馈流。

FeedbackTransformation的固定名称为Feedback

有两个重要参数:

  • input:上游输入StreamTransformation
  • waitTime:默认为0,即永远等待,如果设置了等待时间,一旦超过该等待时间,则计算结束并且不再接收数据。

实例化FeedbackTransformation时,会自动创建一个用于存储反馈边的集合feedbackEdges。

FeedbackTransformation通过定义一个实力方法addFeedbackEdge来收集,

在加入的StreamTransformation的实例有一个要求,

当前FeedbackTransformation跟待加入的StreamTransformation并行度一致。

CoFeedbackTransformation

与FeedbackTransformation类似,也是FlinkDAG中的一个反馈点。

  • 不同之处在于,CoFeedbackTransformation反馈给上游的数据流与上游Transformation的输入类型不同
  • 所以要求上游的Transformation必须是TwoInputTransformation。

四、算子行为

4.1 生命周期管理

1)setup:初始化环境、时间服务、注册监控等。

2)open:该行为由各个具体的算子负责实现,包含了算子的初始化逻辑。

3)close:所有的数据处理完毕之后关闭算子,此时需要去报将所有的缓存数据向下游发送。

4)dispose:该方法在算子生命周期的最后执行阶段,此时算子已经关闭,停止处理数据,进行资源的释放。

StreamTask作为算子的容器,负责管理算子的生命周期。

4.2 异步算子

异步算子的目的是解决与外部系统交互时网络延迟所导致的系统瓶颈问题。

异步算子的两种输出模式

1)顺序输出

先收到的数据先输出,后续数据元素的异步函数调用无论是否先完成,都需要等待,顺序模式可以保证消息不乱序,但是可能增加延迟,降低算子的吞吐量。

2)无序输出

先处理完的数据元素先输出,不保证消息顺序,相比于顺序模式,无序输出模式算子延迟低、吞吐量高。无序输出模式并不是完全无序的,仍然要保持Watermark不能超越其前面数据元素的原则。等待完成队列将按照Watermakr切分成组,组内可以无序输出,组之间必须严格保证顺序。

五、处理函数

5.1 双流Join 即时Join

逻辑如下:

1) 创建一个State对象

2)接收到输入流 1事件后更新Sate。

3)接收到输出流 2的事件后遍历State,根据Join条件进行匹配,将匹配结果发送到下游。

5.2延迟双流Join

在流式数据里,数据可能是乱序的,数据会延迟到达,并且为了提供处理效率,使用小批量模式计算,而不是每个事件触发一次Join计算。

逻辑如下:

1)创建2个state对象,分别缓存输入流1和输入流2的事件。

2)创建一个定时器,等待数据的到达,定时延迟触发Join计算。

3)接收到输入流1事件后更新State。

4)接收到输入流2事件后更新State。

5)定时器遍历State1和State2,根据Join条件进行匹配,将匹配结果发送到下游。

六、数据分区

数据分区在Flink中叫做Partition。

本质上说,分布式计算就是把一个作业切分成子任务Task,将不同的数据交给不同的Task计算。

StreamParitioner

是Flink中的数据流分区抽象接口,决定了在实际运行中的数据流分发模式。

自定义分区

使用用户自定义分区函数,为每一个元组选择目标分区。

ForwardParitioner

用于在同一个OperatorChain中上下游算子之间的数据转发, 实际上数据是直接传递给下游的。

ShufflePartitioner

随机将元素进行分区,可以确保下游的Task能够均匀的获取数据。

ReblancePartitioner

以Round-robin的方式为每个元素分配分区,确保下游的Task可以均匀的获取数据,以免数据倾斜。

RescalingPartitioner

根据上下游Task的数据进行分区。

使用Round-robin选择下游的一个Task进行数据分区,

如上游有2个Source,下游有6个Map,那么每个Source会分配3个固定下游的map,

不会向未分配给自己的分区写入数据。

BroadcastPartitioner

将该记录广播给所有分区,即有N个分区,就把数据复制N份,每个分区1分

KeyGroupStreamPartitioner

keyedStream根据KeyGroup索引编号进行分区,该分区器不是提供给用户来用。

KeyedStream在构造Transformation的时候默认使用KeyedGroup分区形式,从而在底层上支持作业Rescale功能。

七、分布式ID

到此这篇关于解析Flink内核原理与实现核心抽象的文章就介绍到这了,更多相关Flink内核原理核心抽象内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Flink支持哪些数据类型?

    一.支持的数据类型 Flink 对可以在 DataSet 或 DataStream 中的元素类型进行了一些限制.这样做的原因是系统会分析类型以确定有效的执行策略. 1.Java Tuple 和 Scala Case类: 2.Java POJO: 3.基本类型: 4.通用类: 5.值: 6.Hadoop Writables; 7.特殊类型 二.Flink之Tuple类型 Tuple类型  Tuple 是flink 一个很特殊的类型 (元组类型),是一个抽象类,共26个Tuple子类继承Tuple 

  • 大数据HelloWorld-Flink实现WordCount

    所有的语言开篇都是Hello Word,数据处理引擎也有Hello Word.那就是Word Count.MR,Spark,Flink以来开篇第一个程序都是Word Count.那么今天Flink开始目标就是在本地调试出Word Count. 单机安装Flink 开始Flink之前先在本机尝试安装一下Flink,当然FLink正常情况下是部署的集群方式.作者比较穷,机器配置太低开不了几个虚拟机.所以只能先演示个单机的安装. Apache Flink需要在Java1.8+以上的环境中运行 . 所以

  • 详解大数据处理引擎Flink内存管理

    内存模型 Flink可以使用堆内和堆外内存,内存模型如图所示: flink使用内存划分为堆内内存和堆外内存.按照用途可以划分为task所用内存,network memory.managed memory.以及framework所用内存,其中task network managed所用内存计入slot内存.framework为taskmanager公用. 堆内内存包含用户代码所用内存.heapstatebackend.框架执行所用内存. 堆外内存是未经jvm虚拟化的内存,直接映射到操作系统的内存地

  • 浅谈实时计算框架Flink集群搭建与运行机制

    一.Flink概述 1.1.基础简介 主要特性包括:批流一体化.精密的状态管理.事件时间支持以及精确一次的状态一致性保障等.Flink不仅可以运行在包括YARN.Mesos.Kubernetes在内的多种资源管理框架上,还支持在裸机集群上独立部署.在启用高可用选项的情况下,它不存在单点失效问题. 这里要说明两个概念: 边界:无边界和有边界数据流,可以理解为数据的聚合策略或者条件: 状态:即执行顺序上是否存在依赖关系,即下次执行是否依赖上次结果: 1.2.应用场景 Data Driven 事件驱动

  • Java lambda表达式实现Flink WordCount过程解析

    这篇文章主要介绍了Java lambda表达式实现Flink WordCount过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 本篇我们将使用Java语言来实现Flink的单词统计. 代码开发 环境准备 导入Flink 1.9 pom依赖 <dependencies> <dependency> <groupId>org.apache.flink</groupId> <artifactId>

  • Apache FlinkCEP 实现超时状态监控的步骤详解

    CEP - Complex Event Processing复杂事件处理. 订单下单后超过一定时间还未进行支付确认. 打车订单生成后超过一定时间没有确认上车. 外卖超过预定送达时间一定时限还没有确认送达. Apache FlinkCEP API CEPTimeoutEventJob FlinkCEP源码简析 DataStream和PatternStream DataStream 一般由相同类型事件或元素组成,一个DataStream可以通过一系列的转换操作如Filter.Map等转换为另一个Da

  • 解析Flink内核原理与实现核心抽象

    目录 一.环境对象 1.1 执行环境 StreamExecutionEnvironment LocalStreamEnvironment RemoteStreamEnvironment StreamContextEnvironment StreamPlanEnvironment ScalaShellStreamEnvironment 1.2 运行时环境 RuntimeEnvironment SavepointEnvironment 1.3 运行时上下文 StreamingRuntimeConte

  • 解析Tomcat架构原理到架构设计

    目录 一.学习目的 1.1.掌握 Tomcat 架构设计与原理提高内功 1.2.宏观理解一个请求如何与 Spring 联系起来 1.3.提升自己的系统设计能力 二.整体架构设计 2.1.连接器 2.2.封装变与不变 2.3.容器 2.4.请求定位 Servlet 的过程 三.Tomcat 为何打破双亲委派机制 3.1.双亲委派 3.2.Tomcat 热加载 3.3.Tomcat 的类加载器 3.4.Tomcat 类加载器层次 四.整体架构设计解析收获总结 4.1.连接器 4.2.容器 4.3.类

  • 解析Java8 Stream原理

    目录 一.前言 二.Stream流水线解决方案 2.1.操作如何记录 2.2.操作如何叠加 2.3.叠加之后的操作如何执行 一.前言 首先我们先看一个使用Stream API的示例,具体代码如下: 这是个很简单的一个Stream使用例子,我们过滤掉空字符串后,转成int类型并计算出最大值,这其中包括了三个操作:filter.mapToInt.sum.相信大多数人再刚使用Stream API的时候都会有个疑问,Stream是指怎么实现的,是每一次函数调用就执行一次迭代吗?答案肯定是否,因为如果真的

  • 解析Redis Cluster原理

    目录 一.前言 二.为什么需要Redis Cluster 三.Redis Cluster是什么 四.节点负载均衡 五.什么是一致性哈希 六.虚拟节点机制 七.Redis Cluster采用的什么算法 八.Redis Cluster如何做到高可用 8.1.集群如何进行扩容 8.2.高可用及故障转移 九.简单了解gossip协议 十.gossip协议消息类型 十一.使用gossip的优劣 十二.总结 一.前言 Sentinel集群会对Redis的主从架构中的Redis实例进行监控,一旦发现了mast

  • 深入解析kafka 架构原理

     kafka 架构原理 大数据时代来临,如果你还不知道Kafka那就真的out了!据统计,有三分之一的世界财富500强企业正在使用Kafka,包括所有TOP10旅游公司,7家TOP10银行,8家TOP10保险公司,9家TOP10电信公司等等.LinkedIn.Microsoft和Netflix每天都用Kafka处理万亿级的信息.本文就让我们一起来大白话kafka的架构原理. kafka官网:http://kafka.apache.org/ 01 kafka简介 Kafka最初由Linkedin公

  • 解析Linux内核与设备树的编译和烧写

    一.准备材料 可以根据自己的需要准备相应材料: 开发环境:VMware 操作系统:ubuntu 开发版:湃兔i2S-6UB 二.下载Linux内核文件 之前下载过UBoot文件的朋友应该知道,在每个开发版的资料里都有相应的文件,没有的可以找购买开发版的店家要. 下载完成后将文件拷贝到linux系统下进行解压,解压后会的目录如下图所示: 注意:编译时一定要在当前路径下才能编译 三.编译 1.清理项目工程 make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf

  • 深入浅出解析Java ThreadLocal原理

    目录 1.了解ThreadLocal 简介 使用 2.源码解析 – 探究实现思路 threadLocals变量与ThreadLocalMap set(T value) 方法 get() 方法 remove() 方法 实现思路总结 3.InheritableThreadLocal与继承性 ThreadLocal的不可继承性 InheritableThreadLocal实现继承性的源码剖析 如何理解这个继承性 总结 4.存在的内存泄露问题 使用强引用会如何? 使用弱引用会如何? set().get(

  • 全面解析@InsertProvider执行原理

    目录 @InsertProvider执行原理 1.首先要拼接处insert语句 2.ProviderSqlSource实现了sqlSource接口 关于@Insert和@InsertProvider注解用法 1.项目主要结构 2.下面以BlogMapper中的保存Blog实体方法为例 @InsertProvider执行原理 1.首先要拼接处insert语句 其中包含入参,与数据库表字段的映射字段. 在执行Provider类里面的动态插入sql的时候,程序会调用 AbstractSQL这个抽象类,

  • 图文解析AJAX的原理

    先上原理图: 背景: 1.传统的Web网站,提交表单,需要重新加载整个页面. 2.如果服务器长时间未能返回Response,则客户端将会无响应,用户体验很差. 3.服务端返回Response后,浏览器需要加载整个页面,对浏览器的负担也是很大的. 4.浏览器提交表单后,发送的数据量大,造成网络的性能问题. 问题: 1.如何改进? 2.AJAX是什么? 3.有什么优势? 4.有什么缺点? 一.什么是 AJAX 1.为什么需要AJAX 当需要从服务器获取数据,并刷新页面的操作,如果不采用AJAX,则需

  • 深入解析Session工作原理及运行流程

    一.session的概念及特点 session概念:在计算机中,尤其是在网络应用中,称为"会话控制".Session 对象存储特定用户会话所需的属性及配置信息.说白了session就是一种可以维持服务器端的数据存储技术.session主要有以下的这些特点: session保存的位置是在服务端 session一般来说要配合cookie使用,如果用户浏览器禁用了cookie,那么只能使用URL重写来实现session的存储功能 单纯的使用session来存储用户回话信息,那么当用户量较多时

随机推荐