第二部分:Flink 进阶篇

第一部分:Flink基础篇

第二部分:Flink 进阶篇

第三部分:Flink 源码篇

如何保证Exactly-Once语义

 

Flink通过实现"两阶段提交" 和 "状态保存" 来实现端到端的精准一致性语义。 分为以下几个步骤:

开始事务: 创建一个临时文件夹,来写把数据写入到这个文件夹里面;

预提交:   将内存中缓存的数据写入临时文件,并关闭;

正式提交:将之前写完的临时文件放入目标目录下。这代表着最终的数据会有一些延迟;

丢弃:       丢弃临时文件;

若失败发生在预提交成功后,正式提交前。可以根据状态来提交 预提交的数据,也可删除预提交的数据。

Flink中的Watermark机制

① Watermark 是一种衡量 Event Time 进展的机制,通常用来触发窗口计算,可以设定延迟触发;

② Watermark 是用于处理乱序事件的,而正确的处理乱序事件,通常用Watermark 机制结合 window 来实现

③ 基于事件时间,用来触发窗口、定时器等;

④ watermark主要属性就是时间戳,反映的是事件发生的时间,而不是事件处理的时间;

⑤ watermark是单调不减的;

⑥ 数据流中的 Watermark 用于表示 timestamp 小于 Watermark 的数据,都已经到达了,如果后续还有timestamp 小于 Watermark 的数据到达,称为迟到数据。

Watermark是数据吗?怎么生成的?怎么传递的?

Watermark是一条携带时间戳的特殊数据,从代码指定生成的位置,插入到流里面。
一对多:广播
多对一:取最小
多对多:拆分来看,其实就是上面两种的结合

Watermark的生成方式?

间歇性:来一条数据,更新一次watermark
周期性:固定周期更新watermark
官方提供的api是基于周期的,默认200ms,因为间歇性会给系统带来压力。
Watermark=当前最大事件时间 - 乱序时间 - 1ms。   [ 左闭右开的原因 )

Checkpoint机制(检查点)(容错机制)

为了保证state(应用状态)容错,Flink提供了处理故障的措施,这种措施称之为checkpoint(一致性检查点)。checkpoint是Flink实现容错的核心功能,主要是周期性地触发checkpoint,将state生成快照持久化到外部存储系统(比如HDFS)。这样一来,如果Flink程序出现故障,那么就可以从上一次checkpoint中进行状态恢复,从而提供容错保障。

能够将整个应用流图的状态恢复到故障之前的某一状态,保证应用流图状态的一致性。Flink的Checkpoint机制原理来自“Chandy-Lamport algorithm”算法(分布式快照)。

另外,通过checkpoint机制,Flink可以实现Exactly-once语义(Flink内部的Exactly-once,关于端到端的exactly_once,Flink是通过两阶段提交协议实现的)。

从检查点恢复数据:

第一步:重启作业
第二步:从上一次检查点恢复状态数据
第三步:继续处理新的数据

Flink是如何容错的?

Flink实现容错主要靠强大的CheckPoint机制和State机制。
Checkpoint负责定时制作分布式快照、对程序中的状态进行备份;
State 用来存储计算过程中的中间状态;

通过Checkpoint(基于ABS算法)实现容错,具体过程如下:

① JobManager定期向source发送Checkpoint的请求(由代码中的Checkpoint配置决定),向下游发送CheckpointBarrier;

② 每个计算算子收到CheckpointBarrier,进行Barrier对齐,对齐后存储Checkpoint到状态后端;

③ sink节点Barrier对齐后,多个sink确认下Checkpoint是否正常,如果正常JobManager确定本次Checkpoint结束;

④ 中途失败,只需要拿取前面的Checkpoint重新计算,进行恢复。

Flink中的Checkpoint和Spark中的Checkpoint区别

Flink中的Checkpoint主要作用是: 容错机制
Flink中的Checkpoint和Spark中的Checkpoint区别主要有2点:

① flink更轻量,可以根据时间戳更新state,
因为在Flink中Checkpoint是持久化全局的状态 state (keyed state 或 Operator state)的快照,在Flink中==增量==的快照,效率比较高。

对比 Spark :重量的快照,Spark每次全量的快照,Flink 每次增量的快照

spark是每个批次全量保存

② 在Flink中的Checkpoint中又仅一次语义概念和用法 ,而spark checkpoint没有仅一次的概念

③ 其次flink的 checkpoint有三个状态后端,memery、rocksdb、hdfs,所谓的状态后端就是checkpoint的存储位置,
在Spark中checkpoint的存储位置一般保存在HDFS,也可以保存至本地磁盘

但是一般情况下,checkpoint在Flink和Spark中保存的位置没太大区别,基本相同,因为生产情况下一般存HDFS。

状态机制

Flink中的状态机制(状态存储)?

① 什么是状态:     在flink在做计算的过程中,经常需要存储中间状态,像source,sink ;

② 状态的存储:     使用状态后端来管状态和checkpoint的存储 ;

③ 状态的一致性: 通过checkpoint对任务的状态进行快照,以故障恢复的时候保证状态的一致性。

Flink提供了三种状态存储方式(状态后端)


MemoryStateBackend     (内存级的状态后端)

FsStateBackend            (将checkpoint存到远程的持久化文件系统(FileSystem)上)

RocksDBStateBackend   (将所有状态序列化后,存入本地的 RocksDB 中存储)

Flink处理迟到数据的几种方式?

方式1:设置水位线延迟时间。水位线延迟设置,一般设置为毫秒 到 秒级别;

方式2:允许窗口处理迟到数据。如:allowedLateness延长窗口的关闭时间;

方案3:迟到的数据放在侧输出流;

上面的两种方式,都是通过延迟水位线或者延长窗口的方式来处理的,实际处理过程中都会占据资源,不可能一直延迟水位线或者让窗口一直存在,在允许范围内的数据处理完毕之后,还得有一种兜底方案,处理极限情况,那就是直接把迟到的数据输出到侧输出流。

Flink的重启策略

  • 固定延迟重启策略
  • 故障率重启策略
  • 没有重启策略
  • Fallback重启策略(默认是这个Fallback重启策略)

Flink分区策略 (9种)

分区策略是用来决定数据如何发送至下游

  • GlobalPartitioner                   (数据发到下游算子的第一个实例)
  • ShufflePartitioner                  (数据随机分发到下游算子)
  • RebalancePartitioner            (数据循环发送到下游的实例)
  • BroadcastPartitioner             (输出到下游算子的每个实例中)
  • ForwardPartitioner              (上下游算子并行度一样)
  • KeyGroupStreamPartitioner  (按Key的Hash值输出到下游算子)
  • CustomPartitionerWrapper   (用户自定义分区器)
  • BinaryHashPartitioner           (对BinaryRowData这种数据进行hash分区)
  • RescalePartitioner              (根据上下游算子的并行度,循环输出到下游算子)

【实际使用在算子后加分区器】

Flink的序列化如何做

Apache Flink摒弃了Java原生的序列化方法,以独特的方式处理数据类型和序列化,包含自己的类型描述符,泛型类型提取和类型序列化框架。
TypeInformation 是所有类型描述符的基类。它揭示了该类型的一些基本属性,并且可以生成序列化器。TypeInformation 支持以下几种类型:

  • BasicTypeInfo:           任意Java 基本类型或 String 类型
  • BasicArrayTypeInfo:   任意Java基本类型数组或 String 数组
  • WritableTypeInfo:       任意 Hadoop Writable 接口的实现类
  • TupleTypeInfo:           任意的Flink Tuple 类型(支持Tuple1 to Tuple25)。Flink tuples 是固定长度固定类型的Java Tuple实现
  • CaseClassTypeInfo:  任意的 Scala CaseClass(包括 Scala tuples)
  • PojoTypeInfo:            任意的 POJO (Java or Scala),例如,Java对象的所有成员变量,要么是 public 修饰符定义,要么有 getter/setter方法。
  • GenericTypeInfo:        任意无法匹配之前几种类型的类

针对前六种类型数据集,Flink皆可以自动生成对应的TypeSerializer,能非常高效地对数据集进行序列化和反序列化。

Flink中广播变量,使用时需要注意什么?

我们知道Flink是并行的,计算过程可能不在一个 Slot 中进行,那么有一种情况即:当我们需要访问同一份数据。那么Flink中的广播变量就是为了解决这种情况。

我们可以把广播变量理解为是一个公共的共享变量,我们可以把一个dataset 数据集广播出去,然后不同的task在节点上都能够获取到,这个数据在每个节点上只会存在一份。

Flink是如何处理反压的?

flink 内部是基于 producer-consumer 模型来进行消息传递的,flink的反压设计也是基于这个模型。flink 使用了高效有界的分布式阻塞队列,就像 Java 通用的阻塞队列(BlockingQueue)一样。下游消费者消费变慢,上游就会受到阻塞。
其中Flink Web UI 的反压监控提供了SubTask级别的反压监控。

Flink任务延迟高,想解决这个问题,你会如何入手?

在Flink的后台任务管理中,我们可以看到Flink的哪个算子和task出现了反压。最主要的手段是资源调优和算子调优。资源调优即是对作业中的Operator的并发数、CPU、堆内存 等参数进行调优。作业参数调优包括:并行度的设置,State的设置,checkpoint的设置。

Flink的并行度设置

Flink中的任务被分为多个并行任务来执行,其中每个并行的实例处理一部分数据。这些并行实例的数量被称为并行度。我们在实际生产环境中可以从四个不同层面设置并行度:
操作算子层面(Operator Level)
执行环境层面(Execution Environment Level)
客户端层面(Client Level)
系统层面(System Level)
需要注意的优先级:算子层面>环境层面>客户端层面>系统层面。
并行度的设置:一般设为kafka的分区数,达到1:1 
              遵循2的n次方:比如2、4、8、16…..

分布式快照的原理是什么?

Flink的分布式快照是根据Chandy-Lamport算法量身定做的。简单来说就是持续创建分布式数据流及其状态的一致快照。
核心思想是在 input source 端插入barrier,控制barrier的同步来实现snapshot的备份和exactly-once语义。

 Flink内存模型

Join

双流join

在flink中,双流join主要分为2中类型:Join大体分类只有两种:Window Join和Interval Join
① Window Join又可以根据Window的类型细分出3种:
Tumbling Window Join、Sliding Window Join、Session Window Join。
Windows类型的join都是利用window的机制,先将数据缓存在Window State中,当窗口触发计算时,执行Join操作。

② Interval join也是利用state存储数据再处理,区别在于State中的数据有失效机制,依靠数据触发数据清理。
目前Stream Join的结果时数据笛卡尔积。

双流join与传统数据库join区别

数据集合:传统数据库左右两个表的数据集合是有限的,双流JOIN的数据会源源不断的流入;

结果更新:  传统数据库表JOIN是一次执行产生最终结果后退出,双流JOIN会持续不断的产生新的结果;

计算驱动:  双流JOIN由于左右两边的流的速度不一样,需要状态存储,双流驱动。比如:左边数据到来的时候右边数据还没有到来,或者右边数据到来的时候左边数据没有到来,所以在实现中要将左右两边的流数据进行保存,以保证JOIN的语义。

Flink的interval join的实现原理?join不上的怎么办?

底层调用的是keyby+connect ,处理逻辑:
    1)判断是否迟到(迟到就不处理了)

    2)每条流都存了一个Map类型的状态(key是时间戳,value是List存数据)

    3)任一条流,来了一条数据,遍历对方的map状态,能匹配上就发往join方法

    4)超过有效时间范围,会删除对应Map中的数据(不是clear,是remove)
    
Interval join不会处理join不上的数据,如果需要没join上的数据,可以用 coGroup+connect算子实现,或者直接使用flinksql里的left join或right join语法。

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值