我们以下面代码为例:
FlinkKafkaConsumer<String> consumer = new FlinkKafkaConsumer<>("canal_monitor_order_astable", new SimpleStringSchema(), properties);
consumer.setStartFromEarliest();
env.addSource(consumer).flatMap(...).print()
当 Flink 程序启动,leader、blobServer 等都创建完毕,当 ExecutionGraph 构建完成,提交成功之后。就到了,task 正式执行的阶段了。这个时候,一条消息是如何流转的呢?
首先,进入了 Task 的 run 方法
......
/*
这个方法就是用户代码所真正被执行的入口。比如我们写的什么 new MapFunction() 的逻辑,最终就是在这里被执行的
*/
// run the invokable
invokable.invoke();
......
然后就到了 StreamTask 的 invoke 方法,这里是每个算子真正开始执行的地方
......
run();
.....
最为关键的就是 run 方法。
进入 SourceStreamTask run 方法
@Override
// source task 获取数据的入口方法
protected void run() throws Exception {
headOperator.run(getCheckpointLock(), getStreamStatusMaintainer());
}
继续追踪就到了 StreamSource 的 run 方法
......
// 生成上下文之后,接下来就是把上下文交给 SourceFunction 去执行,用户自定义的 run 方法开始正式运行
userFunction.run(ctx);
......
此处的 userFunction 实际上就是 FlinkKafkaConsumer
具体是如何消费消息的可以参考
彻底搞懂 Flink Kafka OffsetState 存储
继续追踪到 RecordWriter
private void emit(T record, int targetChannel) throws IOException, InterruptedExcepti

本文深入分析了Flink中消息的全流程,从FlinkKafkaConsumer开始,详细阐述了Task的run方法、StreamTask的invoke方法、SourceStreamTask的数据获取,以及RecordWriter如何将Java对象转化为byte数组并进行传输。通过Netty进行数据的跨TaskManager传输,最终到达下游算子进行处理。整个过程涉及Flink的反压机制、数据序列化与反序列化等关键环节。
最低0.47元/天 解锁文章
1326

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



