flink入门
1.有状态流式处理引擎的基石
流式处理:每条流数据都经过你编写的代码进行处理
分散式流式处理:保证流式数据相同的key到同一个计算实例上
有状态分散式流式处理:状态会跟着流数据把相同的key分到同一个计算实例上,并且会对状态进行叠加,
当key非常多的时候,状态可能会非常大,所以需要一个状态后端来维护状态。
有状态流式处理面临的挑战:
1⃣️状态容错:
首先需要考虑到精确一次exactly-once的状态容错。
简单场景的容错方法:
有无界数据流从消息队列中输入进来,会把每个状态都保存下来,每个状态都对应一个保存的状态值。
分散式场景下保证全域一致的快照,并且保证不中断运算:
全域一致快照global consistent snapshot:
检查点checkpoint:
会周期性的产生
分散式快照方法(基于chaling-lanbort算法):
先由jobmanager生成一个checkpoint barrier n,类似于一条标记
当我的source遇到这个barrier的时候就会把当前的状态保存到
checkpoint n中,如果source是kafka,那么其实这次保存的状态就是在kafka中消费的偏移量
当checkpoint barrier n流到下一个算子1的时候,下一个算子1就会把状态保存到checkpoint n中
到算子2遇到barrier的时候把状态保存到表格checkpoint n中,jobmanager可以同时保存多个checkpoint,所以不会影响运算的速率
2⃣️状态维护
jvm heap状态后端:
这种状态后端适用于内存比较小的情况,其实就是保存在内存中,只是在分散式
快照的时候需要序列化
rockdb状态后端:
状态可以维护在磁盘中,状态每次维护都需要序列化到磁盘中,
在分散式的情况不需要序列化
3⃣️event-time处理
事件时间event-time:数据流本身的时间
ingestion-time:数据进入flink的时间
window-processing-time:数据在flink中处理的时间
watermarks水位线:
水位线类似于flink中的一条标记,比如一条数据是4点的,如果设了5分钟的wateramrk,
那么这条数据就会等到5分钟之后才开始计算
watermark=当前最大的时间戳-延迟时间(当前最大的时间时间戳maxTS-)
如果watermark>= 窗口的结束时间,这个窗口就会触发关闭操作。
延迟时间的设置:
根据数据的乱序的最大时间来确定延迟时间,延迟时间越大结果越准确但是计算结果出的越慢,延迟时间越小结果越不准确但计算结果出的快。
watermark的传递:
allowlateness
当watermark到的时候,窗口触发计算,输出统计结果,但是窗口不会关闭,等到watermark涨到allowlateness的延迟才会关闭,
比如allowlateness设置了1分钟,watermark到达时这个窗口触发计算,只有等watermark又涨了1分钟才会真正把窗口丢弃。
sideoutputlatedata:
可以把数据放入到侧输出流中,但是放入到侧输出流中的数据不会再叠加了,需要之后再把数据拿出来处理。
4.状态保存和迁移
savepoint保存点:其实就是一个手动产生的检查点
在执行停止之前,比如升级flink,修改flink中的代码这种停止flink应用的时候,就需要
产生一个保存点,最后通过保存点恢复数据追上当前的数据
inputData1 = getRuntimeContext.getState( new ValueStateDescriptor[String]("in1",classOf[String]))
//在classof这里可以传入case类,或者其他类型,flink就是通过这里的类型来生成序列化器,然后在状态checkpoint的时候根据这里的序列化器做序列化的工作
可以在恢复数据的时候通过flink的schema,恢复的时候可以更改schema改变数据结构