Flink总结
TaskManager和Slots
Task Slot 是静态的概念,是指 TaskManager 具有的并发执行能力,可以通过 参数 taskmanager.numberOfTaskSlots 进行配置,而并行度 parallelism 是动态概念, 即 TaskManager 运行程序时实际使用的并发能力,可以通过参数 parallelism.default 进行配置。
Dataflow
Flink 程序由 Source、Transformation、Sink 这三个核心组件组成,Source 主要负责数据 的读取,Transformation 主要负责对属于的转换操作,Sink 负责最终数据的输出,在各个组 件之间流转的数据称为流(streams)。
Flink 的 DataSet API 所使用的 DataSets 其内部也是 stream
一个特定 operator 的 subtask 的个数被称之为其 parallelism(并行度)。
Flink 将 operator 的 subtask 链接在一起形成 task, 每个 task 在一个线程中执行。
Task Slot 是静态的概念,是指 TaskManager 具有的并发执行能力。
- 富函数的特点
富函数有声明周期
Window类型
Window 可以分成两类:
CountWindow:按照指定的数据条数生成一个 Window,与时间无关。
TimeWindow:按照时间生成 Window。 对于 TimeWindow,可以根据窗口实现原理的不同分成三类:滚动窗口(Tumbling Window)、滑动窗口(Sliding Window)和会话窗口(Session Window)。
1. 滚动窗口(Tumbling Windows) 将数据依据固定的窗口长度对数据进行切片。 特点:时间对齐,窗口长度固定,没有重叠。
2. 滑动窗口(Sliding Windows) 滑动窗口是固定窗口的更广义的一种形式,滑动窗口由固定的窗口长度和滑动 间隔组成。 特点:时间对齐,窗口长度固定,有重叠。
3. 会话窗口(Session Windows)由一系列事件组合一个指定时间长度的 timeout 间隙组成,类似于 web 应用的 session,也就是一段时间没有接收到新数据就会生成新的窗口。
特点:时间无对齐。
时间语义
在 Flink 的 流 式 处 理中 , 绝 大 部 分 的 业务都 会 使 用 eventTime,一般只在 eventTime 无法使用时,才会被迫使用 ProcessingTime 或者 IngestionTime。
Watermark是设定延迟触发的机制,用于处理乱序事件的,而正确的处理乱序事件,通常用Watermark机制结合window来实现。
Event Time:事件创建的时间
Ingestion Time:数据进入Flink的时间
Processing Time:执行操作算子的本地系统时间,与机器相关
watermark的特点?
- watermark是一条特殊的数据记录
- watermark必须单调递增,以确保任务的事件时间时钟在向前推进,而不是在后退
- watermark与数据的时间戳相关
水印产生背景
Watermark 是 用 于 处 理 乱 序 事 件 的 , 而 正 确 的 处 理 乱 序 事 件 , 通 常 用 Watermark 机制结合 window 来实现。 数据流中的 Watermark 用于表示 timestamp 小于 Watermark 的数据,都已经 到达了,因此,window 的执行也是由 Watermark 触发的。 Watermark 可以理解成一个延迟触发机制,我们可以设置 Watermark 的延时 时 长 t, 每 次 系 统 会 校 验 已 经 到 达 的 数 据 中 最 大 的 maxEventTime, 然 后 认 定 eventTime 小于 maxEventTime - t 的所有数据都已经到达,如果有窗口的停止时间 等于 maxEventTime – t,那么这个窗口被触发执行。
水印生成策略,一者Periodic(周期性),一者Punctuated(标点符号,间断性)。
水印更新规则和传播
(1)、单并行度
watermark单调递增,一直覆盖较小的watermark。
(2)、多并行度
每个分区都会维护和更新自己的watermark。某一时刻的watermark取所有分区中最小的那一个;也就是说,多并行度的情况下,watermark对齐会取所有channel最小的watermark,详情可参见下面水印传播方式。
ProcessFunction
基于此,DataStream API 提供了一系列的 Low-Level 转换算子。可以访问时间戳、watermark 以及注册定时事件。
状态编程和容错机制
状态始终与特定算子相关联。总的来说,有两种类型的状态:
算子状态(operator state)也叫none key状态,算子的状态作用范围限定为算子任务
- 状态对于同一任务而言是共享的
- 算子状态不能由不同或相同算子的另一个任务访问
键控状态(keyed state)根据输入流数据中定义的key维护和访问,Flink为每个key维护一一个状态实例,并将具有相同键的所有数据,都分区到同一个算子任务中
状态后端(stateBackend)
状态的存储、访问以及维护,由一个可插入的组件决定,这个组件就叫做状态后端(state backend)
状态后端主要负责两件事,本地状态管理,以及检查点checkpoint状态写入远程存储。
可以自定义选状态后端
MemoryStateBackend:内存状态后端,会将键控状态作为内存中的对象进行管理,本地状态将他们存储在TaskManager的JVM堆上,而checkpoint存储在jobmanager的内存中。
特点:快速 低延迟 不稳定
FsStateBackend:将checkpoint存储到远程持久化文件系统上(FileSystem),而对于本地的状态跟menoryStateBackend一样,也会存TaskManager的JVM堆上。同时拥有本地级的访问速度和更好的容错性能,唯一缺点就是保存到checkpoint端的时候效率会低,故障恢复的是会从checkpoint端读取的时候效率会低。
RocksDBStateBackend:将所有的状态序列化后,存入本地的RocksDB中存储
状态一致性
在流处理中,一致性可以分为 3 个级别:
at-most-once: 最多处理一次(处理一次或者不处理)
at-least-once: 最少计算一次
exactly-once: 精确消费一次
端到端(end-2-end)状态一致性
内部保证 —— 依赖 checkpoint
source 端 —— 需要外部源可重设数据的读取位置,例如kafka。
sink 端 —— 需要保证从故障恢复时,数据不会重复写入外部系统。而对于 sink 端,又有两种具体的实现方式:幂等(Idempotent)写入和事务性(Transactional)写入。
幂等写入:所谓幂等操作,是说一个操作,可以重复执行很多次,但只导致一次结果更改,也就是说,后面再重复执行就不起作用了。最典型的就是查询、通知。
事务写入:事务是应用程序中一系列严密的操作,所有操作都必须成功完成,否则在每个操作中所有的更改都会被撤销,具有原子性,一个事务中一系列操作要么全部成功,要么全部失败。
对于事务性写入,具体又有两种实现方式:预写日志(WAL)和两阶段提交
什么是有状态的一致性检查点?
有状态流应用的一致检查点,其实就是所有任务的状态,在某个时间点的一份拷贝(一 份快照) ;这个时间点,应该是所有任务都恰好处理完一个相同的输入数据的时候
如何从检查点恢复状态?
- 遇到故障之后,第一步就是重启应用
- 第二步是从checkpoint中读取状态,将状态重置,从检查点重新启动应用程序后,其内部状态与检查点完成时的状态完全相同
- 第三步:开始消费并处理检查点到发生故障之间的所有数据
什么是保存点?
Flink提供的可以自定义的镜像保存功能,就是保存点
保存点时一个强大的功能,除了故障恢复外,保存点可以用于:由计划的手动备份,更新颖用程序,版本迁移,暂停和重启应用等等
检查点(checkpoint)和保存点(savepoint)的区别?
checkpoint的侧重点是“容错”,即Flink作业意外失败并重启之后,能够直接从早先打下的checkpoint恢复运行,且不影响作业逻辑的准确性。而savepoint的侧重点是“维护”,即Flink作业需要在人工干预下手动重启、升级、迁移或A/B测试时,先将状态整体写入可靠存储,维护完毕之后再从savepoint恢复现场。
savepoint是“通过checkpoint机制”创建的,所以savepoint本质上是特殊的checkpoint。
Flink+Kafka实现一致性语义
什么是复杂事件处理CEP
一个或多个由简单事件构成的事件流通过一定的规则匹配,然后输出用户想得到的数据,满足规则的复杂事件。
特征:
目标:从有序的简单事件流中发现一些高阶特征
输入:一个或多个由简单事件构成的事件流
处理:识别简单事件之间的内在联系,多个符合一定规则的简单事件构成复杂事件
输出:满足规则的复杂事件
- CEP
Next:严格近邻。
followBy:宽松近邻。
followByAny:非确定性宽松近邻:
Flink开发环境
Local模式
启动
${FLINK_HOME}/bin/start-cluster.sh
停止
${FLINK_HOME}/bin/stop-cluster.sh
Standalone Cluster
修改 flink/conf/flink-conf.yaml
jobmanager.rpc.address: node01
修改 /conf/slaves 文件:
node01
node02
node03
分发给另外两台
启动:
./start-cluster.sh
Standalone HA
修改配置文件flink-conf.yaml、masters
#开启HA,使用文件系统作为快照存储
state.backend: filesystem
#启用检查点,可以将快照保存到HDFS
state.checkpoints.dir: hdfs://node01:8020/flink-checkpoints
#使用zookeeper搭建高可用
high-availability: zookeeper
# 存储JobManager的元数据到HDFS
high-availability.storageDir: hdfs://node01:8020/flink/ha/
high-availability.zookeeper.quorum: node01:2181,node02:2181,node03:2181
conf/master
node01:8081
node02:8082
资源同步,到node02中将JobManager设置为自己节点的名称
jobmanager.rpc.address:node02
flink自1.8之后不再提供对应的hadoop编译版本,需