【发布时间】:2023-01-13 09:52:12
【问题描述】:
我正在使用 flink v1.13,有 4 个任务管理器(每 16 个 cpu)和 3800 个任务(默认应用程序并行度为 28)
在我的应用程序中,一位操作员的忙碌时间总是很高(大约 %80 - %90)。
如果我重新启动 flink 应用程序,那么繁忙时间会减少,但在运行 5-10 小时后,繁忙时间会再次增加。
在 grafana 中,我可以看到 ProcessStream 的繁忙时间增加了。这是 PromethuesQuery:avg((avg_over_time(flink_taskmanager_job_task_busyTimeMsPerSecond[1m]))) by (task_name)
ProcessStream 任务中没有背压。为了计算 backPressure 时间,我使用:flink_taskmanager_job_task_backPressuredTimeMsPerSecond
但我找不到任何理由。
这是代码:
private void processOne(DataStream<KafkaObject> kafkaLog) {
kafkaLog
.filter(new FilterRequest())
.name(FilterRequest.class.getSimpleName())
.map(new MapToUserIdAndTimeStampMs())
.name(MapToUserIdAndTimeStampMs.class.getSimpleName())
.keyBy(UserObject::getUserId) // returns of type int
.process(new ProcessStream())
.name(ProcessStream.class.getSimpleName())
.addSink(...)
;
}
// ...
// ...
public class ProcessStream extends KeyedProcessFunction<Integer, UserObject, Output>
{
private static final long STATE_TIMER = // 5 min in milliseconds;
private static final int AVERAGE_REQUEST = 74;
private static final int STANDARD_DEVIATION = 32;
private static final int MINIMUM_REQUEST = 50;
private static final int THRESHOLD = 70;
private transient ValueState<Tuple2<Integer, Integer>> state;
@Override
public void open(Configuration parameters) throws Exception
{
ValueStateDescriptor<Tuple2<Integer, Integer>> stateDescriptor = new ValueStateDescriptor<Tuple2<Integer, Integer>>(
ProcessStream.class.getSimpleName(),
TypeInformation.of(new TypeHint<Tuple2<Integer, Integer>>() {}));
state = getRuntimeContext().getState(stateDescriptor);
}
@Override
public void processElement(UserObject value, KeyedProcessFunction<Integer, UserObject, Output>.Context ctx, Collector<Output> out) throws Exception
{
Tuple2<Integer, Integer> stateValue = state.value();
if (Objects.isNull(stateValue)) {
stateValue = Tuple2.of(1, 0);
ctx.timerService().registerProcessingTimeTimer(value.getTimestampMs() + STATE_TIMER);
}
int totalRequest = stateValue.f0;
int currentScore = stateValue.f1;
if (totalRequest >= MINIMUM_REQUEST && currentScore >= THRESHOLD)
{
out.collect({convert_to_output});
state.clear();
}
else
{
stateValue.f0 = totalRequest + 1;
stateValue.f1 = calculateNextScore(stateValue.f0);
state.update(stateValue);
}
}
private int calculateNextScore(int totalRequest)
{
return (totalRequest - AVERAGE_REQUEST ) / STANDARD_DEVIATION;
}
@Override
public void onTimer(long timestamp, KeyedProcessFunction<Integer, UserObject, Output>.OnTimerContext ctx, Collector<Output> out) throws Exception
{
state.clear();
}
}
【问题讨论】:
-
您在工作流中使用事件时间还是处理时间?如果是事件时间(基于 UserObject.getTimestampMs()),那么您想使用
. registerEventTimeTimer()而不是. registerProcessingTimeTimer()注册计时器。 -
@kkrugler,我正在使用处理时间
-
我看到 CPU 随着时间的推移而增加的一种情况是当状态填满 TM 内存时,并且当您接近满堆时您开始获得大量 GC 活动。
标签: apache-flink flink-streaming