Flink1.17学习笔记(自用)

Flink是什么

核心目标:数据流上的有状态计算

Flink是一个框架分布式处理引擎,用于对无界有界数据进行有状态计算

Flink和Streaming对比
Flink Streaming
计算模型 流计算 微批处理
时间语义 事件时间、处理时间 处理时间
窗口 多、灵活 少、不灵活
状态
流式SQL

Dataset批处理已过时,使用Datastream流处理

Datastream最后执行env.execute() 类似于sparkstream的ssc.start()

集群角色

客户端FlinkClient:代码由客户端获取转换提交给JobManger。

JobManger:Flink集群的管事人,对作业中央调度管理;进一步处理转换分发给TaskManager。

TaskManager干活的人,做数据的处理操作

Flink1.17学习笔记(自用)_第1张图片

 修改conf      --      1 flink-conf.yaml  2.works  3.masters(jobmanager) 分发,修改其他机器的taskmanager.host

bin/start-cluster.sh启动flink集群

默认端口号 8081

部署模式:会话模式、单作业模式 都是在客户端执行

                  应用模式 是直接提交到JobManager上运行,每提交一个应用单独启动一个JobManager,也就是创建一个集群。执行结束后JobManager也关闭了。

运行模式 (集群怎么搭建的)Yarn运行模式:客户端把Flink应用提交给Yarn的ResourceManager,Yarn的ResourceManager会向Yarn的NodeManager申请容器,在这些容器上,Flink会部署JobManager和TaskManager的实例,从而启动集群。Flink会根据运行在JobManager上的作业所需要的Slot数量动态分配TaskManager资源。

历史服务器 端口号:8082

运行时架构-Standlone会话模式为例

Flink1.17学习笔记(自用)_第2张图片

核心概念

并行度:一个特定的算子子任务的个数称为并行度。

设置并行度:1.算子后.setParallelism(2)   2.env.setParallelism(3)全局指定 .都不指定配置文件有默认并行度配置

算子链:上下游算子的合并。

               算子之间的传输关系是一对一和重分区

               算子串在一起的条件是一对一(分发规则是forward)和并行度相同。

                为什么要合并:节省资源,

               算子链的api:1.全局禁用算子链env.disableOperatorChaining()

                                      2.某个算子不参与链化 A.disableChaining()

                                      3.从某个算子开启新链条 算子A.startNewChain()

任务槽:

设置taskmanager的slot数量 配置文件中 taskmanager.numberOfTaskSlots

任务槽的共享组,在同一个作业中,不同任务节点的并行子任务,就可以放到同一个slot上执行。

slot是静态的,并行度是动态的,slot<并行度就不会运行

Yarn应用模式作业提交流程

作业提交给Yarn的ResourceManager,选择一个节点NodeManager启动一个容器,容器里运行ApplicationMaster(JobManager),JobManager里面启动分发器和资源管理器,分发器启动JobMaster生成逻辑流图StreamGraph,经过算子链的优化生成作业流图JobGraph,将作业流图并行化展开生成执行流图ExecutionGraph。向资源管理器注册请求slot,资源管理器向Yarn的ResouceManager申请资源,在NodeManager里创建容器存放TaskManager并向flink的大管家启动成功资源注册slot,分配一下slot,分配任务生成物理流图PhysicalGraph。

Flink1.17学习笔记(自用)_第3张图片

 DataStream API

获取执行环境environment-读取数据源source-转换操作transformation-输出sink-执行execute

源算子source

        从集合读取数据

        从文件读取数据 fromsource

        从kafka读数据  kafka Consumer 消费原则:

一个Topic中的一个Partition只能被一个消费者组中的一个消费者消费,

一个消费者组中的一个消费者可以消费一个Topic中的多个Partition。

最好的情况是消费者个数=Topic的partition

转换算子transformation

        map:一进一出

        filter:过滤

        flapmap:一进多出

聚合算子:

        sum:

        main:

        max:只会取比较字段的最大值,非比较字段保留第一次的值

        maxby:取比较字段的最大值,同时非比较字段取最大值的这条数据的值

        min

        minby

        reduce 思想:两两聚合。从第二个元素开始聚合输入类型=输出类型 类型不能变

富函数:

分区算子:keyby:对数据重分区,不能设置并行度。一个子任务理解为一个分区。一个分区可以存在多个组

输出算子:

处理函数

        process processfunction,拥有富含数的功能,生命周期方法和状态编程。有处理数据的方法,processElement。有onTimer方法,该方法用于定时器TimerService编程。有上下文对象Context ,可以获取定时器编程也可以侧输出流。

        分流

        侧输出流

        合流   

                联合 union 流的类型必须一致,一次可以合并多条流

                连接 connect

                双流联结 join

时间语义:

        事件时间:一个数据产生的时间(时间戳)

        处理时间:数据真正被处理的时间、系统时间。

水位线(watermake):衡量事件时间进展的标记。主要内容就是一个时间戳用来指示当前的事件时间 

        水位线不断增长

        水位线配合窗口一起使用完成对乱序数据的正确处理。

水位线是流处理中对低延迟和结果正确性的一个权衡机制。

watermake+等待时间能够处理延迟数据。

水位线传递原则:

        上游Task向下游 广播水位线。

        下游Task收到上游多个Task的水印,取最小的作为当前水印。

迟到数据处理:

        1.watermake等待时间,设置一个不算特别大的,一般是秒级,在乱序和延迟 取舍

        2.设置一定的窗口允许迟到,只考虑大部分的迟到数据,极端小部分迟到很久的数据不管

        3.极端小部分迟到很久的数据,找到侧输出流,获取到之后可以做各种处理。

窗口

划定一个数据的范围

        1.什么时候触发,输出?  时间进展>=窗口的最大时间戳

        2.窗口是怎么划分的? start=向下取整,取窗口长度的整数倍

                                             end=start+窗口长度

                                              窗口左闭右开 

窗口的分类 滑动、滚动、会话、全局窗口

窗口的使用:1.明确窗口分配器(时间窗口,计数窗口),2.明确窗口算子

增量聚合函数解决聚合过程,全窗口函数聚合确认窗口信息,来一条计算一条。

        ReduceFunction输入和输出类型一致

        AggregateFunction输入和输出类型可以不一致,里面有个累加器

全窗口函数:与增量聚合函数不同,全窗口函数需要先收集窗口中的数据,并在内部缓存起来,等到窗口要输出结果的时候再取出数据进行计算。可以获取窗口的信息(窗口的开始结束时间)

窗口联结Window Join 

间隔联结

Flink的状态托管状态Managed State,(Flink统一管理的)状态的存储访问、故障恢复和重组等一系列问题都由Flink实现;原始状态 Raw State。

Flink的状态编程、状态机制?

算子状态:作用范围是算子,算子的多个并行实例各自维护一个状态

        列表状态

        联合列表状态

        广播状态:广播配置。

按键分区状态:每个分组维护一个状态  首先经过keyby

                值状态:单值,只能维护一个值 

状态后端:管理本地状态的存储方式和位置 本地状态存哪里

                  默认哈希表状态后端HashMapStateBackend,(把状态存放在TaskManager的JVM堆内存中,窗口中收集的数据和触发器以键值对的形式存储,底层是一个哈希表,读写快,存不了太多,受TaskManager内存的限制)内嵌RocksDB状态后端(持久化到本地硬盘,状态被序列化成字节数组,读写慢,但可以存很大的状态)

容错机制

检查点:故障后的恢复。存档读档的思路,将之前某个时间点所有的状态保存下来,这份存档就是所谓的检查点。                 外部存储。

周期性的触发我们应该在所有任务(算子)都恰好处理完一个相同的输入数据的时候,将它们的状态保存下来。

基于Chandy-Lamport算法的分布式快照,可以在不暂停整体流处理的前提下,将状态备份保存到检查点。

当上游任务向多个并行下游任务发送barrier时,需要广播出去;

而当多个上游任务向同一个下游任务传递分界线时,需要在下游任务执行“分界线对齐”操作,也就是需要等到所有并行分区的barrier都到齐,才可以开始状态的保存。

检查点算法的总结:

1、Barrier对齐:一个Task收到所有上游同一个编号的barrier之后,才会对自己的本地状态做备份

        精准一次:在barrier对齐过程中,barrier后面的数据阻塞等待(不会越过barrier)

        至少一次:在barrier对齐过程中,先到的barrier后面的数据不阻塞接着计算

2、非Barrier对齐:一个Task收到第一个barrier时,就开始备份,能保证精准一次

        先到的barrier将本地状态备份,后面的数据接着计算,

        未到的barrier其前面的数据接着输出,同时也保存到备份中

        最后一个barrier到达该Task时,这个Task的备份结束。

保存点:由用户明确地手动触发保存操作,所以就是“手动存盘”。

状态一致性:一致性就是结果的正确性,一般从数据丢失、数据重复评估。

                        最多一次,至少一次,精准一次

端到端的状态一致性:需要考虑flink内部,数据源,外部存储。不能拖后腿

        端到端精确一次:最希望做到,也是最难做到的

                输入端保证:kafka可以保证,可以重置读取数据偏移量。

                Flink端保证:开启检查点且精准一次。

                输出端保证:幂等  利用mysql的主键upsert,hbase的rowkey唯一,redis的set

                                      事务 :预写日志: 有应答机制,没应答会重复写入 至少一次

                                                 两阶段提交:分布式事务的提交 ,先做预提交,等检查点完成之后再做正式提交。

不过两阶段提交虽然精巧,却对外部系统有很高的要求。这里将2PC对外部系统的要求列举如下:

  1. 外部系统必须提供事务支持,或者Sink任务必须能够模拟外部系统上的事务。
  2. 在检查点的间隔期间里,必须能够开启一个事务并接受数据写入。
  3. 在收到检查点完成的通知之前,事务必须是“等待提交”的状态。在故障恢复的情况下,这可能需要一些时间。如果这个时候外部系统关闭事务(例如超时了),那么未提交的数据就会丢失。
  4. Sink任务必须能够在进程失败后恢复事务。
  5. 提交事务必须是幂等操作。也就是说,事务的重复提交应该是无效的。

Flink写入Kafka两阶段提交

在具体应用中,实现真正的端到端exactly-once,还需要有一些额外的配置:

(1)必须启用检查点

(2)指定KafkaSink的发送级别为DeliveryGuarantee.EXACTLY_ONCE

(3)配置Kafka读取数据的消费者的隔离级别

这里所说的Kafka,是写入的外部系统。预提交阶段数据已经写入,只是被标记为“未提交”(uncommitted),而Kafka中默认的隔离级别isolation.level是read_uncommitted,也就是可以读取未提交的数据。这样一来,外部应用就可以直接消费未提交的数据,对于事务性的保证就失效了。所以应该将隔离级别配置

为read_committed,表示消费者遇到未提交的消息时,会停止从分区中消费数据,直到消息被标记为已提交才会再次恢复消费。当然,这样做的话,外部应用消费数据就会有显著的延迟。

(4)事务超时配置

Flink的Kafka连接器中配置的事务超时时间transaction.timeout.ms默认是1小时,而Kafka集群配置的事务最大超时时间transaction.max.timeout.ms默认是15分钟。所以在检查点保存时间很长时,有可能出现Kafka已经认为事务超时了,丢弃了预提交的数据;而Sink任务认为还可以继续等待。如果接下来检查点保存成功,发生故障后回滚到这个检查点的状态,这部分数据就被真正丢掉了。所以这两个超时时间,前者应该小于等于后者。

Flink SQL

你可能感兴趣的:(大数据,#,Flink,flink,大数据)