Flink 问题之 No Watermark (Watermarks are only available if EventTime is used)

问题背景

Flink-1.17.0在集群下,获取Kafka集群数据,进行流模式实时计算,Watermarks提示:No Watermark (Watermarks are only available if EventTime is used)

source数据源是从kafka中读取topic数据,经过算子后sink到mysql表中,但在sink算子处理中,水印显示没有事件时间,导致算子无数据输出,流数据无法实时入库;

如下,因为当前SQL执行JOB的parallelism.default=2,在UI界面看到source输入源SubTasks下有两个子任务指标,其中ID=0无指标显示;

在Sink输出源下Watermarks显示任务的水印提示:No Watermark (Watermarks are only available if EventTime is used),翻译为"无水印(水印仅在使用EventTime时可用)",也就是需要用事件时间,事件时间通常是指流数据中业务字段时间或链接器的接收时间;

但是当前Job是从流数据中取的就是业务时间字段,并且是保证符合时间格式的值;

原因分析

通过查看Flink官方文档关于"Watrmark策略与Kafak连接器"内容,得知Kafka链接器会根据分区数量生成不同分区的Watemark,再合并后经过不同分区算子计算;

官方关于"Watrmark策略与Kafak连接器"说明

生成 Watermark | Apache Flink

在这种情况下,你可以使用 Flink 中可识别 Kafka 分区的 watermark 生成机制。使用此特性,将在 Kafka 消费端内部针对每个 Kafka 分区生成 watermark,并且不同分区 watermark 的合并方式与在数据流 shuffle 时的合并方式相同

同时在官方文档中有提到"处理空闲数据源"说明

生成 Watermark | Apache Flink

如果数据源中的某一个分区/分片在一段时间内未发送事件数据,则意味着 WatermarkGenerator 也不会获得任何新数据去生成 watermark。我们称这类数据源为空闲输入或空闲源。在这种情况下,当某些其他分区仍然发送事件数据的时候就会出现问题。由于下游算子 watermark 的计算方式是取所有不同的上游并行数据源 watermark 的最小值,则其 watermark 将不会发生变化。

为了解决这个问题,你可以使用 WatermarkStrategy 来检测空闲输入并将其标记为空闲状态。WatermarkStrategy 为此提供了一个工具接口:

简单来说,在Flink中kafka连接器会识别每个分片,并为每个分片创建对应Watermark水印,当上游Kafka某个分片在一段时间未发送事件数据,则对应的窗口时间内不会生成Watermark水印,则下游算子(Sink)接收上游的Watermark数据时,是按上游最小Watermark值来计算,则下游算子(Sink)不会发生变化,也就无法触发窗口算子事件;

刚好最近Kafka集群进行服务器更换,对Kafka集群机器节点做了调整,并对部署重新做了优化,有可能导致Flink从Kafka消息topic上读取到了无数据的空闲分片;

知道问题原因后,就好查找方案来解决了,Flink官方文档中明确提到:"你可以使用 WatermarkStrategy 来检测空闲输入并将其标记为空闲状态。"来解决,但这是工程代码的处理方案,我们采用SQL-Clinet执行Job,需要在执行SQL任务时,采用配置方式来处理(也可以默认在flink-config.yaml中全局配置);

查阅官方方案后,有关于table配置"table.exec.source.idle-timeout",当数据源在超时时间内无数据,则标为临时空闲并跳过当前Watermark水印,从而保证下游算子获得的是有数据的Watermark,不会让Job任务处于无数据变化,就像任务阻塞了一样;

配置 | Apache Flink

解决方案

在sql-client 窗口中,执行Job任务SQL前,先设置table.exec.source.idle-timeout=60000,表示1分钟内未收到任何流元素,则该数据表标记为临时空闲;

sql 复制代码
-- 数据源在超时时间内内没有接收到任何元素时,标记为临时空闲,这允许下游任务在空闲时推进其水印,默认为0不启用 
-- (不启用,如果kafka多分区消息不均衡或有无效分区,会导制下游任务水印无效并无法输出算子结果) 
SET table.exec.source.idle-timeout=60000;

配置上述参数后,继续执行SQL脚本JOB任务,约经过一小段时间后(1分钟),下游Sink算子的Watermark不在提示"No Watermark (Watermarks are only available if EventTime is used)",并正常显示Watermark数值;

流实时数据也能正常经过算子聚合计算后入库了;

相关推荐
小泊客1 小时前
使用讯飞星火 Spark X1-32K 打造本地知识助手
大数据·分布式·spark·大模型应用·本地知识助手
wangqiaowq2 小时前
StarRocks 3.5.7 安装部署
大数据
PPT百科2 小时前
PPT插入的音乐怎么让它播放到某一页就停?
大数据·职场和发展·powerpoint·职场·ppt模板
码上地球2 小时前
大数据成矿预测系列(八) | 从定性到概率:逻辑回归——地质统计学派的“集大成者”
大数据·逻辑回归
拓端研究室2 小时前
专题:2025中国医疗器械出海现状与趋势创新发展研究报告|附160+份报告PDF、数据、可视化模板汇总下载
大数据·人工智能·pdf
zskj_zhyl3 小时前
科技向暖,银发无忧:十五五规划中智慧养老的温度革命
大数据·人工智能·科技·物联网·生活
muxue1784 小时前
Hadoop集群搭建(上):centos 7为例(已将将安装所需压缩包统一放在了/opt/software目录下)
大数据·hadoop·centos
q***23924 小时前
【SQL技术】不同数据库引擎 SQL 优化方案剖析
数据库·sql
阿里云大数据AI技术4 小时前
【跨国数仓迁移最佳实践11】基于 MaxCompute Resource & Quota策略优化实现资源管理性能与成本最优平衡
大数据
Elastic 中国社区官方博客5 小时前
Elasticsearch 的结构化文档配置 - 递归分块实践
大数据·人工智能·elasticsearch·搜索引擎·ai·全文检索·jenkins