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数值;

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

相关推荐
soso196832 分钟前
DataWorks快速入门
大数据·数据仓库·信息可视化
The_Ticker37 分钟前
CFD平台如何接入实时行情源
java·大数据·数据库·人工智能·算法·区块链·软件工程
java1234_小锋42 分钟前
Elasticsearch中的节点(比如共20个),其中的10个选了一个master,另外10个选了另一个master,怎么办?
大数据·elasticsearch·jenkins
Elastic 中国社区官方博客43 分钟前
Elasticsearch 开放推理 API 增加了对 IBM watsonx.ai Slate 嵌入模型的支持
大数据·数据库·人工智能·elasticsearch·搜索引擎·ai·全文检索
我的运维人生44 分钟前
Elasticsearch实战应用:构建高效搜索与分析平台
大数据·elasticsearch·jenkins·运维开发·技术共享
大数据编程之光1 小时前
Flink Standalone集群模式安装部署全攻略
java·大数据·开发语言·面试·flink
B站计算机毕业设计超人1 小时前
计算机毕业设计SparkStreaming+Kafka旅游推荐系统 旅游景点客流量预测 旅游可视化 旅游大数据 Hive数据仓库 机器学习 深度学习
大数据·数据仓库·hadoop·python·kafka·课程设计·数据可视化
永乐春秋1 小时前
WEB-通用漏洞&SQL注入&CTF&二次&堆叠&DNS带外
数据库·sql
在下不上天3 小时前
Flume日志采集系统的部署,实现flume负载均衡,flume故障恢复
大数据·开发语言·python
智慧化智能化数字化方案3 小时前
华为IPD流程管理体系L1至L5最佳实践-解读
大数据·华为