前面讲了 ResourceManager 和 SlotManager 的启动流程,这篇聚焦 TaskManager 的启动设计。TaskManager 是 Flink 集群的工作节点,负责执行 Task 和提供 Slot 资源。你有没有想过,一个 TaskManager 进程从启动到就绪,经历了哪些步骤?TaskExecutor 内部有哪些核心组件?注册 ResourceManager 和创建 Slot 的流程是怎样的?这篇从流程设计角度完整剖析。
一、TaskManager 整体架构
下面这张图是 TaskManager 整体架构,包括 TaskExecutor 核心组件、TaskManagerServices 基础服务和外部交互。

TaskManager 运行在独立的 JVM 进程中,核心是 TaskExecutor,内部包含六个核心组件:
- SlotTable:管理本地 Slot 的分配和释放,记录每个 Slot 的状态(FREE/ALLOCATED)。
- MemoryManager:管理堆内和堆外内存,将内存池分配给 Task 使用,支持内存泄漏检测。
- NetworkEnvironment:管理网络缓冲区,维护 ResultPartition 和 InputGate,负责 Task 间的数据传输。
- IOManager:管理磁盘 IO,负责 spill 临时文件和 shuffle 数据的读写。
- TaskManagerServices:服务集合,包含心跳、指标、文件系统、Blob 缓存等基础服务。
- TaskExecutorGateway:RPC 网关,接收 JobManager 的 Task 部署和 Slot 分配请求。
TaskManager 与 JobManager 和 ResourceManager 保持交互:JobManager 通过 JobMaster 部署 Task、通过 SlotPool 申请和释放 Slot;ResourceManager 负责注册 TaskManager、心跳管理和 Slot 分配。
二、TaskManager 启动完整流程
下面这张图是 TaskManager 启动完整流程,包括6步启动流程、关键类、服务初始化顺序和常见问题。

TaskManager 启动分为6步:
第1步:TaskManagerRunner 启动。JVM 进程启动,加载配置,创建 TaskManagerRunner 实例。解析命令行参数,加载 flink-conf.yaml 配置,初始化日志系统。这是整个启动流程的入口。
第2步:TaskManagerServices 创建。创建 TaskManagerServices,包含 MemoryManager、NetworkEnvironment、IOManager、HeartbeatServices、MetricRegistry 等基础服务。根据配置初始化内存池和网络缓冲区,这一步是资源准备阶段。
第3步:TaskExecutor 创建。创建 TaskExecutor 实例,初始化 SlotTable,创建 numberOfTaskSlots 个 Slot。注册 RPC 服务,启动 TaskExecutorGateway,准备接收 JobManager 的请求。
第4步:启动 RPC 服务。启动 Akka RPC 服务,TaskExecutor 开始监听 RPC 请求。注册到 HighAvailabilityServices,获取 ResourceManager 地址,准备建立连接。
第5步:注册 ResourceManager。向 ResourceManager 发送 registerTaskManager 请求,上报 TaskManager 资源信息(Slot 数、内存、CPU)。RM 注册成功后返回确认,建立心跳连接。
第6步:Slot 创建与心跳。创建 SlotReport,向 RM 上报所有 Slot 状态(FREE)。启动心跳定时器,定期向 RM 和 JM 上报心跳和 Slot 状态。TaskManager 进入就绪状态,等待接收 Task 部署请求。
三、核心服务初始化
TaskManagerServices 是 TaskManager 的基础服务集合,按以下顺序初始化:
MemoryManager → NetworkEnvironment → IOManager → HeartbeatServices → MetricRegistry → BlobCacheService → TaskExecutor
MemoryManager 内存管理
java
public class MemoryManager {
private final long totalMemorySize;
private final long pageSize;
private final Map<MemorySegment, Long> allocatedSegments;
public static MemoryManager create(
TaskManagerServicesConfiguration taskManagerServicesConfiguration) {
long memorySize = taskManagerServicesConfiguration.getMemorySize();
long pageSize = taskManagerServicesConfiguration.getPageSize();
return new MemoryManager(memorySize, pageSize);
}
}
MemoryManager 管理堆内和堆外内存,将内存划分为固定大小的 MemorySegment,分配给 Task 使用。支持内存泄漏检测,Task 完成后检查是否所有分配的内存都已释放。
NetworkEnvironment 网络环境
java
public class NetworkEnvironment {
private final NetworkBufferPool networkBufferPool;
private final TaskEventDispatcher taskEventDispatcher;
public NetworkEnvironment(
NetworkBufferPool networkBufferPool,
TaskEventDispatcher taskEventDispatcher) {
this.networkBufferPool = networkBufferPool;
this.taskEventDispatcher = taskEventDispatcher;
}
}
NetworkEnvironment 管理网络缓冲区,维护 ResultPartition(输出)和 InputGate(输入),负责 Task 间的数据传输。网络缓冲区大小由 taskmanager.memory.network.fraction 配置,默认占 TaskManager 总内存的 10%。
四、注册 ResourceManager 与 Slot 创建
下面这张图是注册 ResourceManager 与 Slot 创建流程,包括5步注册流程、Slot 创建可视化、心跳机制、配置和最佳实践。

注册 ResourceManager 流程
注册分为5步:
- 获取 RM 地址:从 HA 服务(ZooKeeper/K8s)获取 ResourceManager Leader 地址。
- 建立 RPC 连接:通过 Akka RPC 连接 ResourceManagerGateway。
- 发送注册请求:调用 registerTaskManager,上报资源信息(Slot 数、内存、CPU)。
- RM 注册确认:RM 分配 ResourceID,返回 RegistrationResponse。
- 建立心跳:启动心跳定时器,定期上报心跳和 Slot 状态。
Slot 创建
注册成功后,根据 taskmanager.numberOfTaskSlots 配置创建 N 个 Slot:
java
public class SlotTable {
private final Map<SlotID, Slot> slots;
private final int numberOfSlots;
public void addSlots(TaskManagerLocation taskManagerLocation, int numberOfSlots) {
for (int i = 0; i < numberOfSlots; i++) {
SlotID slotId = new SlotID(taskManagerLocation.getResourceID(), i);
Slot slot = new Slot(slotId, taskManagerLocation, i);
slots.put(slotId, slot);
}
}
public SlotReport createSlotReport() {
return new SlotReport(slots.values().stream()
.map(slot -> new SlotStatus(slot.getSlotId(), slot.getResourceProfile(),
slot.getJobId(), slot.getAllocationId()))
.collect(Collectors.toList()));
}
}
每个 Slot 初始状态为 FREE,加入 SlotTable 管理。创建 SlotReport 上报给 ResourceManager,RM 将这些 Slot 注册到 SlotManager 中,等待分配给作业使用。
五、心跳机制
TaskManager 启动后与 ResourceManager 和 JobManager 保持心跳:
java
public class HeartbeatManagerImpl<I, O> implements HeartbeatManager<I, O> {
private final long heartbeatInterval;
private final long heartbeatTimeout;
private final ScheduledExecutorService scheduledExecutor;
public void monitorTarget(ResourceID resourceID, HeartbeatTarget<O> heartbeatTarget) {
heartbeatTargets.put(resourceID, heartbeatTarget);
scheduledExecutor.scheduleAtFixedRate(
() -> heartbeatTarget.requestHeartbeat(
new Heartbeat<>(resourceID, lastHeartbeatPayload)),
heartbeatInterval,
heartbeatInterval,
TimeUnit.MILLISECONDS);
}
}
心跳机制的关键点:
- 心跳间隔默认 10 秒(heartbeat.interval)
- 心跳超时默认 50 秒(heartbeat.timeout),超过该时间无心跳则被 RM 剔除
- 心跳携带 SlotReport,包含所有 Slot 的当前状态
- RM 收到心跳后更新 TaskManager 最后活跃时间,检查是否有超时的 TaskManager
六、关键配置与最佳实践
关键配置
yaml
# 每个 TaskManager 的 Slot 数
taskmanager.numberOfTaskSlots: 1
# TaskManager 总内存
taskmanager.memory.process.size: 1728m
# Task 堆内存
taskmanager.memory.task.heap.size: 512m
# 托管内存(排序、哈希表、RocksDB 状态后端)
taskmanager.memory.managed.size: 512m
# 网络内存比例
taskmanager.memory.network.fraction: 0.1
# 心跳间隔
heartbeat.interval: 10s
# 心跳超时
heartbeat.timeout: 50s
# 注册超时
taskmanager.registration.timeout: 5min
最佳实践
-
合理配置 Slot 数:根据 CPU 核数配置 numberOfTaskSlots,通常 1-4 个,避免过多导致资源竞争。Slot 数过多会导致每个 Slot 分配的内存和 CPU 减少,影响 Task 执行性能。
-
配置足够内存:taskmanager.memory.process.size 根据作业需求配置,堆内和堆外内存比例合理。状态后端使用 RocksDB 时需要足够的托管内存,网络密集型作业需要调大网络内存比例。
-
监控心跳状态:关注心跳超时告警,及时发现 TaskManager 异常。心跳超时通常由网络问题、GC 停顿或 TaskManager 负载过高导致,需要结合日志和指标排查。
-
使用 Slot Sharing:默认开启 Slot Sharing,多个算子共享一个 Slot,提高资源利用率。但隔离性要求高的场景(如内存密集型算子)可以关闭 Slot Sharing,为每个算子分配独立 Slot。
-
配置 HA 高可用:生产环境配置 ZooKeeper/K8s HA,ResourceManager 故障切换时 TaskManager 自动重新注册,不需要重启 TaskManager,提高集群可用性。
七、总结
Flink TaskManager 启动是一个6步流程:TaskManagerRunner 启动 → TaskManagerServices 创建 → TaskExecutor 创建 → 启动 RPC 服务 → 注册 ResourceManager → Slot 创建与心跳。核心组件包括 SlotTable、MemoryManager、NetworkEnvironment、IOManager、TaskManagerServices 和 TaskExecutorGateway。注册 ResourceManager 分为5步,注册成功后创建 N 个 FREE 状态的 Slot,通过心跳机制定期上报状态。理解启动流程有助于排查 TaskManager 注册失败、内存分配失败、网络缓冲区不足、心跳超时被剔除等常见问题。