Flink源码之StreamTask启动流程

每个ExecutionVertex分配Slot后,JobMaster就会向Slot所在的TaskExecutor提交RPC请求执行Task,接口为TaskExecutorGateway::submitTask

复制代码
CompletableFuture<Acknowledge> submitTask(
        TaskDeploymentDescriptor tdd, JobMasterId jobMasterId, @RpcTimeout Time timeout); 

TaskDeploymentDescriptor 中包含当前Task的执行逻辑、Job信息、输入输出信息

submitTask 方法核心就是构造org.apache.flink.runtime.taskmanager.Task实例,该实例继承自Runnable接口,有个Thread成员变量,构造完成后就启动线程执行Task逻辑。

复制代码
TaskExecutor::submitTask
Task.startTaskThread
Task.run
Task.doRun
Task::setupPartitionsAndGates //初始化Task的输入输出
RuntimeEnvironment::new //封装task执行上下文信息
Task::loadAndInstantiateInvokable //TaskInvokables实例化
StreamTask::new
    StreamTask::createRecordWriterDelegate //创建Writer,为每个StreamEdge创建一个Writer
    StreamTask::createStateBackend //创建StateBackend,一个task一个StateBackend实例
    StreamTask::createCheckpointStorage
    SubtaskCheckpointCoordinatorImpl::new 
Task::restoreAndInvoke
TaskInvokable::restore 
TaskInvokable::invoke //处理输入元素
TaskInvokable::cleanUp

Task的Invokable Class是在StreamGraph中添加Operator形成StreamNode时确定的,对不同的算子有不同的InvokableClass:

  • SourceStreamTask.class //LegacySource算子
  • SourceOperatorStreamTask //Source算子
  • OneInputStreamTask.class //输入是一个算子
  • TwoInputStreamTask:class //输入是两个算子
  • MultipleInputStreamTask.class //输入有多个算子

以上这些类都继承自org.apache.flink.streaming.runtime.tasks.StreamTask

在调用TaskInvokable::restore时会执行:

复制代码
StreamTask::restore
StreamTask::restoreInternal //创建OperatorChain
RegularOperatorChain::new
OperatorChain::new
OperatorChain::createOutputCollector
OperatorChain::createOperatorChain
OperatorChain::createOperator
StreamOperatorFactoryUtil.createOperator  //创建Operator,在每个算子的StreamConfig中定义了每个Operator具体类型,比如StreamMap, StreamFlatMap
SimpleOperatorFactory::createStreamOperator //创建StreamOperator包装了用户函数,, StreamOperator包装了代码中用户函数,会调用用户函数中的open/close等生命周期函数
	AbstractUdfStreamOperator::setup
	AbstractStreamOperator::setup //设置用用自定义函数中的RuntimeContext成员变量
    	StreamingRuntimeContext::new  //
    
StreamTask::init //子类做初始化,创建InputGate、StreamTaskInput、DataOutput及InputProcessor
StreamTask::restoreGates
	StreamTask::createStreamTaskStateInitializer
		StreamTaskStateInitializerImpl::new //
    OperatorChain::initializeStateAndOpenOperators //调用每个Operator的initializeState和Open方法
    	AbstractStreamOperator::initializeState 
			StreamTaskStateInitializerImpl::streamOperatorStateContext //此时会创建keyedStatedBackend和operatorStateBackend
		StreamOperatorStateHandler::new //初始化StreamOperator的stateHandler成员变量,用于状态管理
		StreamOperatorStateHandler::initializeOperatorState
		    StateInitializationContextImpl::new
			AbstractUdfStreamOperator::initializeState//调用用户定义函数中的initializeState方法,可获取Operator State
				StreamingFunctionUtils::restoreFunctionState
		StreamingRuntimeContext::setKeyedStateStore
	StreamOperator::open //调用getRuntimeContext().getState可获取keySate
StreamTask::invoke
StreamTask::runMailboxLoop
MailboxProcessor::runMailboxLoop
StreamTask::processInput

整个过程在StreamTask.java的注释中有说明:

复制代码
 * -- invoke()
 *       |
 *       +----> Create basic utils (config, etc) and load the chain of operators
 *       +----> operators.setup()
 *       +----> task specific init()
 *       +----> initialize-operator-states()
 *       +----> open-operators()
 *       +----> run()
 *       +----> finish-operators()
 *       +----> close-operators()
 *       +----> common cleanup
 *       +----> task specific cleanup()
  1. 首先创建OperatorChain,依次创建出每个StreamOperator
  2. 调用Operator的setup方法,初始化StreamingRuntimeContext
  3. 调用子类init方法初始化
  4. 调用initializeState初始化每个算子的状态,此时会为每个StreamOperator创建keyedStatedBackend和operatorStateBackend,然后会调用用户定义函数中的initializeState方法,用于创建Operator State
  5. 调用算子的open方法,便于用户在自定义函数open中进行初始化,比如初始化keyState
  6. 调用processInput处理流中数据

SourceStreamTask重载了StreamTask::processInput,该方法中直接起一个线程调用SourceFunction::run方法。

OneInputStreamTask则不同,它重载了StreamTask的init方法,在init方法中创建了StreamOneInputProcessor

复制代码
OneInputStreamTask::init
OneInputStreamTask::createCheckpointedInputGate
OneInputStreamTask::createDataOutput //创建StreamTaskNetworkOutput
OneInputStreamTask::createTaskInput //创建StreamTaskNetworkInput
StreamOneInputProcessor::new

在StreamTask::processInput则是调用InputProcessor::processInput不断读取数据进行处理

复制代码
StreamOneInputProcessor::processInput
StreamTaskNetworkInput::emitNext(StreamTaskNetworkOutput)
AbstractStreamTaskNetworkInput::emitNext //循环不断从buffer中读取StreamElement
处理
AbstractStreamTaskNetworkInput::processElement
    StreamTaskNetworkOutput::emitRecord //调用operator的setKeyContextElement和processElement
        OneInputStreamOperator::setKeyContextElement
        AbstractStreamOperator::setKeyContextElement1
        AbstractStreamOperator::setCurrentKey //
            StreamOperatorStateHandler::setCurrentKey //设置状态当前key
        Input::processElement  //调用StreamOperator的processElement方法

以上Task从提交到起线程执行起来的整个过程,在初始化过程中为每个StreamOperator进行状态后端的初始化相当重要,后续处理流的过程中会使用这些状态后端存储管理状态。

相关推荐
大大大大晴天8 小时前
从 Prompt 到 Tool Calling:AI Agent 如何稳定连接程序世界
大数据·agent
key_3_feng9 小时前
反馈闭环:Agent 自我进化的真正引擎
大数据·agent
EnCi Zheng9 小时前
Agent 如何进行工具调用:从一次 Function Calling 到生产级工具编排的完整链路
大数据·人工智能·agent·ai编程·工具调用
GlobalInfo9 小时前
重磅发布 | 2026年船体清洁机器人行业研究报告:市场规模、发展前景与十五五战略地图
大数据·人工智能·机器人
海宇服务9 小时前
零信任架构实战:基于海宇全能小微企业报告构建自动化园区商户免押租赁资信核验网关
大数据·人工智能·架构·自动化
热文新讯11 小时前
迎进博·话疗愈:2026酒店“疗愈睡眠”闭门研讨会在沪举行
大数据·人工智能·物联网
NailiConveyor13 小时前
柔性物流方案如何适配工厂升级?自动化输送流水线定制要点
大数据·运维·自动化·制造·业界资讯
梦影_13 小时前
MySQL进阶教程(五)—— SQL调优(下)
android·大数据·数据库·后端·sql·mysql·database
没落之王14 小时前
三易五行看宋朝的三界确立
大数据·人工智能·算法
samLi062016 小时前
【数据集】水星逆行及相关日期窗口数据(1973-2025年)
大数据