sunny123456

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 :: 管理 ::

Flink遇到的问题汇总(持续更新)

基础:API代码

一.KeyBy相关:

Exception in thread "main" org.apache.flink.api.common.InvalidProgramException: Specifying keys via field positions is only valid for tuple data types. Type: PojoType<pojo.Student, fields = [name: String, score: Integer, uuid: String]>

使用keyby或者minby相关的函数时,数据流对象必须是Tuple类型,不可以为pojo类型,如果用pojo,就必须使用 字段名称,下面的写法就没问题。

二. window API & 版本相关:

Caused by: java.lang.RuntimeException: Record has Long.MIN_VALUE timestamp (= no timestamp marker). Is the time characteristic set to 'ProcessingTime', or did you forget to call 'DataStream.assignTimestampsAndWatermarks(...)'?

运行的代码如下:

DataStream<Student> minStudentDS = studentDS
.keyBy("uuid")
.timeWindow(Time.seconds(15))
.minBy("score");

这是因为上面代码,是符合标准的Flink1.9的API(尚硅谷视频中是这样写的):直接使用timeWindow,后面一个时间参数指滚动,两个时间指滑动,默认为processingTime 即 算子执行的时间。1.12已经过时了,测试将jar包改回1.9,上面正常代码运行。

而我代码中,flink是1.12版本,12版本默认时间为事件时间,这种API必须指定事件时间字段和watermark,上面这种写法编译没问题,执行时就会报错。如果不修改上面过时的API,就要额外添加下面代码,修改时间语义默认为算子执行时间,添加后上面的代码正常运行。

env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime);

而1.12版本标准API:是在window方法后,传递明确的窗口类型对象为参数: 滚动/滑动/事件时间/执行时间 排列组合共能传递4个对应的类:

  1. SlidingEventTimeWindows
  2. SlidingProcessingTimeWindows
  3. TumblingProcessingTimeWindows
  4. TumblingEventTimeWindows

代码如下:

DataStream<Student> minStudentDS = studentDS
.keyBy(Student::getUuid)
.window(TumblingProcessingTimeWindows.of(Time.seconds(15)))
.minBy("score");

框架原理类

一.背压相关:

一般遇到最终结果不能实时到达,可以观察一下UI界面,DAG中有红色部分,再通过backPressure处查看上下行消费数据的条数和比例。背压往往是红色task的下游task处理不过来导致的。不解决的话,上游(有聚合状态的话)数据过多导致OOM,下游频繁gc降低性能,数据丢失,延迟加载影响业务结果等等。

可以看到这个job,产生背压的下游节点的并行度为1,因为它是一个cdc任务(mysql to hudi),并且使用sql API,底层使用一个全窗口往下游写,默认并行度为1。这里就需要改为stream API的方式,在sink处使用自定义sink,如果没有全窗口聚合需求且下游支持,批量写入下游节点,来增加这个task的吞吐速度。

这里有个技巧,可以修改sink的并行度,与上游算子保持相同,尝试让sinkTask和上游task合并。合并后性能将大大提升。这里我用自定义sink代替sql,并修改并行度以后,两个subtask合并,UI上可以看到两个task已经合并,方法可以查询"flink算子合并条件",最终sink侧完成快速写入,完全不用担心背压的产生。

平时常见的背压问题(最常见的就是sink侧性能,倾斜,内存这三个):

  1. 因为join导致的倾斜:倾斜问题解决方案网上一抓一把。
  2. 对象过多没有释放导致的内存不足,GC频繁:可以通过监控软件看到问题,然后设置tm内存参数,gc参数,合理的solt来规避。
  3. cpu运行情况等:网上见过,用grafana抓到具体tm的cpu情况,发现是slot过多,cpu全部大部分用来gc。
  4. 理论上内存泄漏,链接泄漏,线程泄漏,死锁,线程休眠不合理,日志输出不合理,内核问题导致线程夯住等等所有能导致task执行变慢的原因都可以产生背压。

二.


原文链接:https://zhuanlan.zhihu.com/p/471426016

posted on 2025-07-14 14:53  sunny123456  阅读(20)  评论(0)    收藏  举报