Flink 中的水印操作
流处理中的乱序
当 flink 以 EventTime 模式处理流数据时,它会根据数据里的时间戳来处理基于时间的算子。但是由于网络、分布式等原因,会导致数据乱序的情况。
kafka中的数据是全局无序,怎么实现KAFKA中的数据有序

watermark解决乱序
不以事件时间作为触发计算的条件,而是根据Watermark判断是否触发。
当Watermark的时间戳等于Event中携带的EventTime时候,上面场景(Watermark=EventTime)的计算结果如下:

如果想正确处理迟来的数据可以定义Watermark生成策略为 Watermark = EventTime -5s, 如下:

基于SQL的水印
实现场景:
使用Socket模拟接收数据
设置WaterMark,设置的逻辑:在第一条数据进来时,设置WaterMark为0,指定第一条数据的时间戳后,获取该时间戳与当前 WaterMark的最大值,并将最大值设置为下一条数据的WaterMark,以此类推
-- 创建映射表 CREATE TABLE MyTable ( item STRING, ts TIMESTAMP(3), -- TIMESTAMP 类型的时间戳 WATERMARK FOR ts AS ts - INTERVAL '0' SECOND ) WITH ( 'connector' = 'socket', 'hostname' = 'node1', 'port' = '9999', 'format' = 'csv' ); -- 设置滚动窗口进行聚合计算 SELECT TUMBLE_START(ts, INTERVAL '5' SECOND) AS window_start, TUMBLE_END(ts, INTERVAL '5' SECOND) AS window_end, TUMBLE_ROWTIME(ts, INTERVAL '5' SECOND) as window_rowtime, item,count(item) as total_item FROM MyTable GROUP BY TUMBLE(ts, INTERVAL '5' SECOND), item;
数据有序的场景
测试数据:
hello,2022-03-25 16:39:45 hello,2022-03-25 16:39:46 hello,2022-03-25 16:39:47 hello,2022-03-25 16:39:48 hello,2022-03-25 16:39:49 hello,2022-03-25 16:39:50
数据无序的场景
测试数据:
hello,2022-03-25 16:39:45 hello,2022-03-25 16:39:46 hello,2022-03-25 16:39:47 hello,2022-03-25 16:39:48 hello,2022-03-25 16:39:49 hello,2022-03-25 16:39:50 hello,2022-03-25 16:39:47 hello,2022-03-25 16:39:46 hello,2022-03-25 16:39:51 hello,2022-03-25 16:39:52 hello,2022-03-25 16:39:53 hello,2022-03-25 16:39:54 hello,2022-03-25 16:39:55
设置迟到时间:
drop table MyTable; -- 允许Flink处理延迟以5秒内的迟到数据,修改最大乱序时间 CREATE TABLE MyTable ( item STRING, ts TIMESTAMP(3), -- TIMESTAMP 类型的时间戳 WATERMARK FOR ts AS ts - INTERVAL '5' SECOND ) WITH ( 'connector' = 'socket', 'hostname' = 'node1', 'port' = '9999', 'format' = 'csv' ); SELECT TUMBLE_START(ts, INTERVAL '5' SECOND) AS window_start, TUMBLE_END(ts, INTERVAL '5' SECOND) AS window_end, TUMBLE_ROWTIME(ts, INTERVAL '5' SECOND) as window_rowtime, item,count(item) as total_item FROM MyTable GROUP BY TUMBLE(ts, INTERVAL '5' SECOND), item;

基于DataStream的水印
水印策略设置
WatermarkStrategy 可以在 Flink 应用程序中的两处使用:
-
第一种是直接在数据源上使用
-
第二种是直接在非数据源的操作之后使用
第一种方式相比会更好,因为数据源可以利用 watermark 生成逻辑中有关分片/分区(shards/partitions/splits)的信息。使用这种方式,数据源通常可以更精准地跟踪 watermark,整体 watermark 生成将更精确。直接在源上指定 WatermarkStrategy意味着你必须使用特定数据源接口,例如与kafk

文章详细介绍了Flink中水印(Watermark)的概念和作用,如何通过水印解决流处理中的数据乱序问题,包括固定延迟生成水印和单调递增水印策略。此外,还探讨了数据有序和无序场景下的示例,以及如何处理延迟数据和设置多并行度下的水印。最后,提到了Flink的容错机制,如Checkpoint和重启策略,确保系统在面对故障时的恢复能力。
最低0.47元/天 解锁文章
3346

被折叠的 条评论
为什么被折叠?



