Apache Flink是一个框架和分布式处理引擎,用于对有界流和无界流数据进行有状态的计算,Flink设计为在所有常见的集群环境中运行,以内存速度和任何规模莫执行计算。
Flink是java和Scala语言编写的
流计算:基于源源不断的数据流,来数据就计算的持续计算
状态:流式计算的中间结果
计算框架:类似MapReduce框架,分析数据
分布式:分析处理数据是,可以启动多个task,并行处理
分布式计算思想:分而治之,先分再合
安装部署本地集群:将不同进程运行在同一台机器上,只有一台机器
一个JM(JobManger)和一个TM(Taskmanager)
Standalone集群:类似于hadoop+yarn集群,管理集群资源和分配资源给Flink Job运行task
一个JM和多个TM
StandaloneHA集群:解决JM单点故障问题
Flink On Yarn集群:Flink集群运行在Yarn管理的NM资源容器槽Slot中
运行模式Session模式:启动一个Flink集群,供多个Job使用,main方法运行在client
运行Job需要先启动Flink集群,启动Yarn集群,yarn-session.sh 开辟资源,然后再flink run运行task
Per-Job模式:每个Job启动一个Flink集群,Job资源隔离,main方法运行在client
直接flink run提交job
application模式:每个Job启动一个Flink集群,Job资源隔离,main方法运行在JM
以上两种模式,main放阿飞在客户端执行,需要获取flink运行需要的依赖项,并生产JobGraph
,提交到集群的操作都会在实时平台所在的机器上执行,造成服务器压力,提交任务还会将本地flink所有jar包上次到hdfs,带来大量网络io
application模式将用于的main方法在集群中运行,将程序和依赖打包进一个可执行的jar包中,集群的入口application负责调用其中main犯法来生产jobgraph。
编程模型Stateful Stream Processing 最底层
DataStream、DataSet API 核心API
TableAPI 声明时DSL链式编程
SQL SQL查询
开发和打包部署流程1、创建Maven 项目
2、添加依赖jar包
3、编写程序
4、打成jar包,提交到集群运行
开发DataStream:Flink中,将数据抽象为DataStream,分为有界的数据流和无界的数据流
是分布式的数据集合,对DataSteam调用方法函数处理就是对数据进行处理。
DataStreamSource:从数据源获取的数据流
KeyedStream:分组了的流
SingleOutputStreamOperator:调用转换函数产生的流
IterativeStream:迭代流
开发流式程序步骤:
1.执行环境 StreamExecutionEnvironment:getExecutionEnvironment()、create...
2.数据源(Source) DataSource:fromElement、fromSource、addSource
3.数据处理
4.数据输出
5.触发执行env.execute()
并行度:对于每个算子,都可以设置并行度,可以从算子级别、执行环境级别、客户端级别、系统级别设置,影响范围依次增大,优先级依次减小,建议只使用前三个
Source数据源元素:fromElement
集合:fromCollection、fromSequence
文件:readTextFlie、readFile
自定义:
1、SourceFunction(非并行数据源)
2、RichSourceFunction(rich,富函数版本)
3、ParallelSourceFunction(并行数据源)
4、RichParallelSourceFunction(rich,富函数版本)
map、flatMap
reduce:(temp、item)聚合
filter:过滤
keyBy:将流分组,按照数据中某个字段
min、minBy、max、maxBy、求流最大最小值,min、max只关心指定的字段值
union、connect:union进行相同类型数据流的关联,connect进行两个(可以是不同类型)数据流的关联,关联后分别处理,union可以连多个,connect只能连接两个
sideOutput:旁路输出:分割流或者获取流一部分进行输出,对数据进行标记,然后获取有标记的数据:需要先定义OutputTag标签,再调用DataStream底层process函数处理,进行划分,最后再获取流
上游数据,划分给下游的时候的分配方式
1、GlobalPartitioner:将所有数据发送到下游的某一个算子
2、BroadcastPartitioner:将数据发送到下游的所有算子
3、ForwardPartitioner:将数据发送到下游对应的算子,上下游并行度一致
4、ShufflePartitioner:随机选择一个下游算子发送数据
5、RebalancePartitioner:轮询的方法发送到下游的每一个算子
6、RescalePartitioner:基于上下游并行度,将记录轮询分配到下游某些算子(不是所有算子,只是其中一部分)
7、自定义
富函数:1、带有open和close生命周期的方法,这些方法只执行一次,在算子调用前和调用后做一下处理,用于初始化和最后的善后处理
2、可以获取运行而缓解的上下文对象context
底层函数:processFunction可以其他上层算子的功能,但是使用起来复杂,功能更加强大
连接器Connector 数据源连接器(DataSourceConnector)支持反序列化:Flink读数据需要进行反序列化,需要进行设置
Flink从Kafka读取消费数据是比较常见的
KafkaSource:FlinkKafkaConsumer(旧)、KafkaSource
分区发现规则:Kafka新增分区,以及分区Topic可支持增加,使用正则表达式传入Topic参数,可以支持Topic发现
SinkConnector:支持序列化:Flink输出数据需要支持序列化
KafkaSink:FlinkKafkaProducer
JdbcSink:sink到支持jdbc的外部系统
StreamFlieSink(旧)、Fliesink:sink到外部文件系统
Redissink:sink到Redis
批处理高级特性1.累加器Accumulator
可以很好的观察task在运行期间的数据变化,与MR的counter的类似,task端不可读,只可以累加
2.广播变量Broadcast
可以将集合数据进行广播到TaskManager中,供subTask、task使用,在task端是只读的,多个task公用,可以减少内存开销
3.分布式缓存Cache
可以将文件数据进行缓存到TaskManger中,供subTask、task使用,与广播变量的区别就是数据是存在磁盘文件中的
窗口Window将无界的流,以划分窗口,对窗口数据批处理的方式进行计算
窗口分类:
时间窗口:以一定长度时间划分、具体还分为滑动窗口和滚动窗口
计数窗口:每固定多少条数据来了一后,触发窗口,分为滑动窗口、滚动窗口
会话窗口:设置一个时间间隔,用户第一次访问,会话开始,当用户两次访问时间超过间隔时,划分窗口触发计算
窗口分配器:将数据流的每条数据分配到对应的窗口
窗口函数:当满足窗口触发计算的条件后,对窗口数据调用窗口函数处理 有reduce、aggregate、process等
Flink时间语义EventTime 事件事件:数据产生的时间
IngestiionTime 到达时间:数据进入flink系统时间
ProcessingTime 处理时间:数据被算子处理的时间
乱序延迟数据处理乱序:数据由于网络波动和延迟,导致到达flink系统的时间乱序
解决方式:设置watermark水位线,watermark水位线是一个时间戳类型的,等于eventTime-最大允许乱序时间,当watermark时间大于窗口结束时间时,才触发计算,适用场景是数据延迟不宜太长,否则数据不能及时计算,实时性无法保证。一般2s以内比较好
延迟:数据由于网络波动,延迟较长时间才到达,次数已经触发窗口计算
解决方式:设置允许延迟时间Allowed Lateness,在允许延迟时间内,每来一条数据即可触发窗口计算,时间不宜太长,太长了无法保证数据实时性,并且窗口的持续计算保存会占用资源
超时:数据延迟特别久,此时过了允许的延迟时间,如果不做处理,会丢弃(前面两步如果不设置,数据超时也会被丢弃)
解决方式:sideOutput:旁路输出
将过期的数据进行旁路输出,单独处理
Flink高级APIState:状态:流式数据处理时,比如计算数据量,中间的sum结果就是状态
Kafka数据源读取时,保存kafka的消费偏移量offset也是状态
分类:
算子状态:整个算子的状态,一般有ListState和BroadcastState
键控状态:每个key维护一个状态,一般有ValueState、ListState、MapState、ReducingState
Broadcast State等
Checkpoint 检查点
检查点:用于故障恢复,容灾的数据保存机制
分为状态后端保存和状态checkpoint文件保存
实现方式:
Jobmanager的CheckpointCoordinator进行检查点机制
Flink的JobManager创建CheckpointCoordinator;
Coordinator向所有的SourceOperator发送Barrier栅栏(理解为执行Checkpoint的信号);
SourceOperator接收到Barrier之后,暂停当前的操作(暂停的时间很短,因为后续的写快照是异步的),并制作State快照, 然后将自己的快照保存到指定的介质中(如HDFS), 一切 ok之后向Coordinator汇报并将Barrier发送给下游的其他Operator;
其他的如TransformationOperator接收到Barrier,重复第2步,最后将Barrier发送给Sink;
Sink接收到Barrier之后重复第2步;
Coordinator接收到所有的Operator的执行ok的汇报结果,认为本次快照执行成功;
checkpoint三种级别:
1、MemoryStateBackend:状态保存到TM内存,checkpoint保存JM内存
2、FsStateBackend:状态保存TM内存,checkpint保存到文件系统比如HDFS
3、RocksDBStateBackend:状态保存到RocksDB内置数据库(类似redis内存数据库),checkpoint保存到文件系统HDFS
End-to-End Exactly-Once(端到端精确性一次语义)三个必要条件:
1、数据源支持重设消费的起始位置(数据源)
2、启用checkpoint机制+分布式快照机制+分布式快照算法(Flink内部)
3、数据接收端需要支持事务或者幂等性写入(接受端):at least once +去重/幂等性
接收端需要支持事务或者幂等性写入,Nosql都支持幂等性写入,或者需要支持事务,事务的两种方式:1、预写日志(WAL)2、二阶段提交(Sink 发送barrier完成,先预提交,Coordinator收到所有checkpoint成功消息后才真正提交)d
Flink Stream高级函数ProcessFunction的KeyedPorcessFunction
需要实现的方法:
processElement:对流中每条数据进行处理
onTimer:设置定时器,可以定时调度方法执行
BroadcastState广播状态的使用
小表进行广播,跟大表进行join,减少内存消耗
使用connect方法,对小表数据大表数据进行分别处理,小表定义广播数据,
大表只能读取,不能修改
窗口聚合类型
全量聚合:窗口触发计算后,对窗口所有数据进行处理
增量聚合:每来一条数据进行一次处理,等触发窗口计算后,直接返回当前的状态
Flink运行架构组件:Resource Manager、Dispatcher、JobMaster、TaskManager
Flink JobManager是Flink集群主进程,它包含三个不同组件
Dispatcher、TaskManager、及每个Job的JobMaster
Dispatcher 负责接收用户提交的作业,并且负责为这个作业拉起一个新的JobMaster
ResourceManager 负责资源的管理,在整个Flink集群中只有一个
JobMaster 负责管理作业的运行,在一个Flink集群中可能同时有多个作业运行,每个作业都有自己的JobMaster组件
作业提交流程
1、Flink任务提交后、Client向HDFS上传Flink的Jar包和配置,之后向Yarn ResourceManger提交任务,RM分配container资源并通知对应的NM启动ApplicationMaster;
2、ApplicationMaster 启动后加载 Flink 的 Jar 包和配置构建环境,然后启动 JobManager
3、之后 ApplicationMaster 向 ResourceManager申 请 资 源 启 动TaskManager , ResourceManager分 配Container资 源 后 , 由ApplicationMaster通 知 资 源 所 在 节 点 的NodeManager启 动TaskManager
4、NodeManager 加载 Flink 的 Jar 包和配置构建环境并启动 TaskManager,TaskManager启动后向 JobManager 发送心跳包,并等待 JobManager 向其分配任务
运行时任务调度原理1、Flink程序执行的时候,会被映射为一个StreamDataFlow,一个 Streaming Dataflow 是==由一组 Stream 和 Transformation Operator 组成
2、Client端根据SDF图进行优化,将相连的并行度相同并且数据传输模式为One to One的进行合并得到JobGraph
3、JobManager根据JobGraph加入并行度得到一个执行图
4、最后再进行优化,一个slot可以运行多个operator,但是operator不能是相同的
最终任务需要的slot个数,跟任务重大的并行度的operator相关,槽位数相同
Flink的TableAPI&SQL发展:flink1.9之前,api使用复杂,性能优化也不好,对于流计算和批处理分两套api
Flink1.9之后,阿里收购Flink母公司,融入阿里自己优化的Blink
Flink1.2版本,TableAPI&SQL逐渐完善
Flink1.9之后,两个查询处理器Flink Query Processor和Blink Query Processor,一个是flink的,一个是阿里优化的blink的
1.12版本后,默认处理器改为blink
使用TableAPI&SQL需要导入依赖包
使用步骤:
1.添加依赖
2.构建表执行环境
3.创建输入表(inputTable)和输出表(outputTable)需要进行配置
4.使用SQL或者DSL进行查询(inser select)
Connector可以连接K’afka,FileSystem,JDBC,Hbase等,构建表映射关系,使用tableAPI或者SQL处理分析数据
Flink SQL client
Flink提供了可以进行sql查询的客户端
Flink与Hive的集成
使用Hive进行元数据管理
1、持久化元数据到Hive的metaStore
2、利用Flink读取hive的表
FlinkCDC
变更数据获取的简称,使用CDC可以从数据库中获取已提交的更改并将这些更改发送到下游,供下游使用,这些变更可以包括INSERT、DELETE、UPDATE等
优点:基于CDC同步数据,不用经过Flume和Kafka、直接从数据库表导入数据到Flink,并且支持全量导入和实时增量导入。