前面几篇分别讲了 ResourceManager、Dispatcher、JobManager 的启动流程,这篇聚焦 Flink 资源管理的核心------SlotManager。你有没有想过,JobMaster 向 ResourceManager 申请 Slot 后,SlotManager 内部是如何找到合适的 Slot 并分配的?Slot 的 FREE、PENDING、ALLOCATED、RELEASED 四种状态是如何转换的?当没有空闲 Slot 时,PendingSlotRequest 是如何等待和超时的?这篇从 ResourceManager 启动讲起,深入 SlotManager 内部启动流程,剖析 Slot 分配机制和状态机,把 SlotManager 从启动到 Slot 分配的完整链路讲透。
一、SlotManager 整体架构
下面这张图是 Flink SlotManager 整体架构,包括 JobMaster 层(Slot 申请方)、SlotManager 核心组件、ResourceManager 管理、TaskManager 提供 Slot,以及 Slot 状态机。

1.1 SlotManager 在 Flink 集群中的定位
SlotManager 是 Flink 集群资源管理的核心组件,运行在 ResourceManager 进程内部,负责:
- Slot 分配:接收 JobMaster(通过 SlotPool)的 Slot 请求,查找合适的空闲 Slot 并分配
- Slot 回收:Task 执行完成或作业取消后,回收已分配的 Slot,标记为空闲
- Slot 状态管理:管理所有 TaskManagerSlot 的状态(FREE/PENDING/ALLOCATED/RELEASED)
- Slot 请求超时:管理 PendingSlotRequest 的超时,超时后取消请求并通知 JobMaster
- Slot 状态同步:通过 SlotStatusSyncer 定期同步 Slot 状态到 ResourceManager
SlotManager 不直接与 JobMaster 或 TaskManager 通信,而是通过 ResourceManager 转发。JobMaster 的 SlotPool 向 ResourceManager 发送 requestSlot,RM 转发给 SlotManager;SlotManager 找到 Slot 后通过 RM 通知 TaskManager 分配。
1.2 SlotManager 核心组件
SlotManager 内部有四个核心组件,各司其职:
TaskManagerSlot:TaskManager 上的 Slot 实例。每个 Slot 对应 TaskManager 上的一个资源单元,管理 Slot 的状态(FREE/PENDING/ALLOCATED/RELEASED),记录 Slot 所属的 TaskManager、资源信息、分配的 JobId 等。
PendingSlotRequest:待处理的 Slot 请求。当没有 FREE Slot 时,SlotManager 创建 PendingSlotRequest,等待 Slot 可用或超时。包含请求 ID、资源需求、超时时间、JobId 等信息。
SlotStatusSyncer:Slot 状态同步器。定期将 SlotManager 中的 Slot 状态同步到 ResourceManager,确保 RM 和 SlotManager 的 Slot 状态一致,支持状态查询和监控。
SlotManagerConfiguration:SlotManager 配置参数。包括 Slot 请求超时时间、TaskManager 超时时间、最大 Slot 数、Slot 回收策略等,控制 SlotManager 的行为和性能。
1.3 Slot 四种状态
Slot 有四种状态,构成完整的状态机:
- FREE:空闲可用状态。Slot 未被分配,可以接收新的 Slot 请求。TaskManager 注册时,其所有 Slot 初始为 FREE。
- PENDING:分配中状态。Slot 已被 SlotManager 选中,等待 TaskManager 确认分配。此时 Slot 被临时占用,不能分配给其他请求。
- ALLOCATED:已分配状态。Slot 已分配给 Task,Task 正在执行中。此时 Slot 被 Task 占用,直到 Task 完成或作业取消。
- RELEASED:已释放状态。Slot 已被释放,资源回收。释放后 Slot 回到 FREE 状态,可以重新分配。
二、ResourceManager 启动与 SlotManager 启动
SlotManager 的启动始于 ResourceManager 的启动。ResourceManager 在 onStart() 中调用 slotManager.start() 启动 SlotManager。
2.1 ResourceManager 启动流程
java
public class ResourceManagerImpl<WorkerType extends ResourceIDRetrievable>
extends FencedRpcEndpoint<ResourceManagerId>
implements ResourceManager<WorkerType> {
private final SlotManager slotManager;
private final ResourceManagerDriver resourceManagerDriver;
private final TaskManagerManager taskManagerManager;
@Override
public void onStart() throws Exception {
try {
// 1. 启动 SlotManager(必须在其他组件之前)
slotManager.start();
// 2. 启动 ResourceManagerDriver
resourceManagerDriver.initialize();
// 3. 启动 TaskManagerManager
taskManagerManager.start();
// 4. 启动 Leader 选举
leaderElectionService.start(this);
} catch (Exception e) {
throw new ResourceManagerException("Could not start the ResourceManager.", e);
}
}
@Override
public void grantLeadership(UUID newLeaderSessionID) {
// 成为 Leader 后激活
leaderSessionID = newLeaderSessionID;
slotManager.setLeaderSessionId(newLeaderSessionID);
registerMetrics();
}
}
ResourceManager 启动后,SlotManager 是第一个启动的组件。因为后续的 TaskManager 注册、Slot 分配都依赖 SlotManager。ResourceManager 成为 Leader 后,调用 slotManager.setLeaderSessionId() 设置 Leader 会话 ID,SlotManager 开始正常工作。
2.2 SlotManager 在 ResourceManager 中的创建
java
public abstract class ResourceManagerFactory<WorkerType extends ResourceIDRetrievable> {
protected SlotManager createSlotManager(
ResourceManagerRuntimeServices resourceManagerRuntimeServices,
ResourceManagerConfiguration resourceManagerConfiguration) {
// 创建 SlotManagerImpl
return new SlotManagerImpl(
resourceManagerConfiguration.getSlotManagerConfiguration(),
resourceManagerRuntimeServices.getScheduledExecutor(),
...);
}
}
public class ResourceManagerRuntimeServices {
public static ResourceManagerRuntimeServices fromConfiguration(
Configuration configuration,
HighAvailabilityServices haServices) throws Exception {
// 创建 SlotManagerConfiguration
SlotManagerConfiguration slotManagerConfiguration =
SlotManagerConfiguration.fromConfiguration(configuration);
return new ResourceManagerRuntimeServices(
slotManagerConfiguration,
...);
}
}
SlotManager 在 ResourceManagerFactory 中创建,传入 SlotManagerConfiguration(从 Flink 配置读取)和 ScheduledExecutor(用于超时检查)。默认实现是 SlotManagerImpl。
三、SlotManager 内部启动流程源码
下面这张图是 SlotManager 启动完整流程,包括 ResourceManager 启动5步、SlotManager 内部启动6步、启动顺序横条、生命周期状态机和8个关键类。

3.1 SlotManagerImpl 构造函数
java
public class SlotManagerImpl implements SlotManager {
private final SlotManagerConfiguration configuration;
private final ScheduledExecutor scheduledExecutor;
// TaskManagerSlot 映射:TaskManagerId → TaskManagerSlot 列表
private final Map<ResourceID, Map<SlotID, TaskManagerSlot>> taskManagerSlots;
// PendingSlotRequest 映射:AllocationID → PendingSlotRequest
private final Map<AllocationID, PendingSlotRequest> pendingSlotRequests;
// Slot 状态监听器
private SlotStatusListener slotStatusListener;
// Slot 状态同步器
private SlotStatusSyncer slotStatusSyncer;
// Leader 会话 ID
private UUID leaderSessionId;
// 运行状态
private boolean running;
public SlotManagerImpl(
SlotManagerConfiguration configuration,
ScheduledExecutor scheduledExecutor,
...) {
this.configuration = configuration;
this.scheduledExecutor = scheduledExecutor;
this.taskManagerSlots = new HashMap<>();
this.pendingSlotRequests = new HashMap<>();
this.running = false;
}
}
构造函数中初始化了核心数据结构:
taskManagerSlots:TaskManagerSlot 的映射,按 TaskManagerId 分组,管理所有注册的 SlotpendingSlotRequests:PendingSlotRequest 的映射,管理所有等待中的 Slot 请求running:运行状态标记,初始为 false
3.2 start() 启动流程
java
@Override
public void start() {
if (!running) {
running = true;
// 1. 创建并启动 SlotStatusSyncer
this.slotStatusSyncer = new SlotStatusSyncer(
this,
configuration.getSlotStatusSyncInterval());
slotStatusSyncer.start();
// 2. 注册 Slot 状态监听器(由 ResourceManager 设置)
// slotStatusListener 在 setSlotStatusListener() 中设置
// 3. 启动 Slot 请求超时检查
// 通过 scheduledExecutor 定期检查超时的 PendingSlotRequest
scheduledExecutor.schedule(
this::checkTimeoutSlotRequests,
configuration.getSlotRequestTimeout(),
TimeUnit.MILLISECONDS);
LOG.info("SlotManager started.");
}
}
start() 方法是 SlotManager 启动的入口,主要做三件事:
- 启动 SlotStatusSyncer:创建并启动 Slot 状态同步器,定期同步 Slot 状态
- 注册 Slot 状态监听器:监听器由 ResourceManager 通过 setSlotStatusListener() 设置
- 启动超时检查:通过 scheduledExecutor 定期检查超时的 PendingSlotRequest
3.3 Slot 状态监听器
java
public interface SlotStatusListener {
// Slot 状态变化时回调
void slotStatusChanged(SlotID slotId, SlotStatus newStatus);
}
@Override
public void setSlotStatusListener(SlotStatusListener slotStatusListener) {
this.slotStatusListener = slotStatusListener;
}
private void notifySlotStatusChange(SlotID slotId, SlotStatus newStatus) {
if (slotStatusListener != null) {
slotStatusListener.slotStatusChanged(slotId, newStatus);
}
}
SlotManager 通过 SlotStatusListener 通知 ResourceManager Slot 状态变化。ResourceManager 实现这个接口,在 Slot 状态变化时更新内部状态,并通知 JobMaster 或 TaskManager。
3.4 超时检查机制
java
private void checkTimeoutSlotRequests() {
if (!running) {
return;
}
long currentTime = System.currentTimeMillis();
long timeout = configuration.getSlotRequestTimeout().toMillis();
// 遍历所有 PendingSlotRequest,检查是否超时
Iterator<Map.Entry<AllocationID, PendingSlotRequest>> iterator =
pendingSlotRequests.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<AllocationID, PendingSlotRequest> entry = iterator.next();
PendingSlotRequest request = entry.getValue();
if (currentTime - request.getCreationTime() > timeout) {
// 超时,取消请求
iterator.remove();
notifySlotRequestTimeout(request);
LOG.warn("Slot request {} timed out.", request.getAllocationId());
}
}
// 继续下一次检查
if (running) {
scheduledExecutor.schedule(
this::checkTimeoutSlotRequests,
timeout,
TimeUnit.MILLISECONDS);
}
}
超时检查是 SlotManager 的重要机制。当 PendingSlotRequest 超过配置的超时时间(默认5分钟)仍未分配到 Slot 时,SlotManager 取消该请求并通知 JobMaster。JobMaster 收到超时通知后,可以选择重试或失败。
四、Slot 分配机制与状态机
下面这张图是 Slot 分配机制与状态机,包括 Slot 分配6步直线流程、Slot 四种状态机、状态转换说明、SlotManager 内部4个核心组件、关键配置和常见问题。

4.1 Slot 分配完整流程
java
@Override
public CompletableFuture<Acknowledge> requestSlot(
JobID jobId,
AllocationID allocationId,
ResourceProfile resourceProfile,
String targetAddress,
ResourceManagerId resourceManagerId) {
// 1. 检查是否有 FREE Slot 满足资源需求
TaskManagerSlot freeSlot = findFreeSlot(resourceProfile);
if (freeSlot != null) {
// 2. 找到 FREE Slot,标记为 PENDING
freeSlot.assignPendingAllocation(allocationId, jobId);
// 3. 创建 PendingSlotRequest(用于超时和状态跟踪)
PendingSlotRequest pendingRequest = new PendingSlotRequest(
allocationId, jobId, resourceProfile, freeSlot.getSlotId());
pendingSlotRequests.put(allocationId, pendingRequest);
// 4. 通过 ResourceManager 通知 TaskManager 分配 Slot
// 实际调用 taskExecutorGateway.requestSlot(...)
CompletableFuture<Acknowledge> allocateFuture =
allocateSlotOnTaskManager(freeSlot, allocationId, jobId);
// 5. TaskManager 确认分配后,标记为 ALLOCATED
allocateFuture.thenAccept(ack -> {
freeSlot.markAllocated();
pendingSlotRequests.remove(allocationId);
notifySlotStatusChange(freeSlot.getSlotId(), SlotStatus.ALLOCATED);
});
return allocateFuture;
} else {
// 没有 FREE Slot,创建 PendingSlotRequest 等待
PendingSlotRequest pendingRequest = new PendingSlotRequest(
allocationId, jobId, resourceProfile, null);
pendingSlotRequests.put(allocationId, pendingRequest);
// 通知 ResourceManager 申请新资源(启动新 TaskManager)
notifyResourceShortage(resourceProfile);
return CompletableFuture.completedFuture(Acknowledge.get());
}
}
Slot 分配的完整流程:
- 查找 FREE Slot:遍历所有 TaskManagerSlot,查找 FREE 状态且满足资源需求的 Slot
- 标记 PENDING:找到 Slot 后标记为 PENDING,临时占用,防止分配给其他请求
- 创建 PendingSlotRequest:创建待处理请求,用于超时和状态跟踪
- 通知 TM 分配:通过 ResourceManager 向 TaskManager 发送 allocateSlot 请求
- 标记 ALLOCATED:TaskManager 确认分配后,标记为 ALLOCATED,完成请求
- 无 Slot 时等待:没有 FREE Slot 时,创建 PendingSlotRequest 等待,同时通知 RM 申请新资源
4.2 Slot 状态转换
java
public class TaskManagerSlot {
private final SlotID slotId;
private final ResourceID taskManagerId;
private final ResourceProfile resourceProfile;
private SlotState state; // FREE / PENDING / ALLOCATED / RELEASED
private AllocationID allocationId;
private JobID jobId;
// FREE → PENDING
public void assignPendingAllocation(AllocationID allocationId, JobID jobId) {
Preconditions.checkState(state == SlotState.FREE,
"Slot is not in FREE state: " + state);
this.state = SlotState.PENDING;
this.allocationId = allocationId;
this.jobId = jobId;
}
// PENDING → ALLOCATED
public void markAllocated() {
Preconditions.checkState(state == SlotState.PENDING,
"Slot is not in PENDING state: " + state);
this.state = SlotState.ALLOCATED;
}
// ALLOCATED → RELEASED → FREE
public void releaseSlot() {
Preconditions.checkState(state == SlotState.ALLOCATED || state == SlotState.PENDING,
"Slot is not in ALLOCATED or PENDING state: " + state);
this.state = SlotState.RELEASED;
this.allocationId = null;
this.jobId = null;
// 释放后回到 FREE
this.state = SlotState.FREE;
}
}
Slot 状态转换有严格的前置条件检查:
- FREE → PENDING:只能从 FREE 转换,分配请求时触发
- PENDING → ALLOCATED:只能从 PENDING 转换,TaskManager 确认分配时触发
- ALLOCATED/PENDING → RELEASED → FREE:Task 完成或作业取消时触发,释放后回到 FREE
4.3 TaskManager 注册与 Slot 注册
java
@Override
public void registerTaskManager(
ResourceID taskManagerId,
TaskExecutorRegistration taskExecutorRegistration) {
// 1. 创建 TaskManagerSlot 列表
Map<SlotID, TaskManagerSlot> slots = new HashMap<>();
int numberOfSlots = taskExecutorRegistration.getNumberOfSlots();
for (int i = 0; i < numberOfSlots; i++) {
SlotID slotId = new SlotID(taskManagerId, i);
TaskManagerSlot slot = new TaskManagerSlot(
slotId,
taskManagerId,
taskExecutorRegistration.getDefaultSlotResourceProfile());
slots.put(slotId, slot);
}
// 2. 注册到 taskManagerSlots
taskManagerSlots.put(taskManagerId, slots);
// 3. 通知 Slot 状态变化(所有新 Slot 为 FREE)
for (SlotID slotId : slots.keySet()) {
notifySlotStatusChange(slotId, SlotStatus.FREE);
}
// 4. 尝试分配等待中的 PendingSlotRequest
tryAllocatePendingRequests();
}
TaskManager 注册时,SlotManager 为其每个 Slot 创建 TaskManagerSlot 实例,初始状态为 FREE。注册完成后,SlotManager 尝试为等待中的 PendingSlotRequest 分配 Slot。
五、核心类源码剖析
5.1 SlotManager
SlotManager 是 Slot 管理器的接口,定义了 Slot 分配和回收的核心方法:requestSlot(申请 Slot)、cancelSlotRequest(取消 Slot 请求)、registerTaskManager(注册 TaskManager)、unregisterTaskManager(注销 TaskManager)、setSlotStatusListener(设置 Slot 状态监听器)、start/close(启动和关闭)。SlotManager 接口隔离了具体实现,方便扩展和测试。
5.2 SlotManagerImpl
SlotManagerImpl 是 SlotManager 的默认实现,是 Slot 分配的核心。内部维护 taskManagerSlots(所有注册的 Slot)和 pendingSlotRequests(等待中的 Slot 请求)两个核心数据结构。核心方法:start() 启动 SlotStatusSyncer 和超时检查;requestSlot() 查找 FREE Slot 并分配;checkTimeoutSlotRequests() 检查超时请求;registerTaskManager() 注册 TaskManager 的 Slot。SlotManagerImpl 运行在 ResourceManager 的主线程中,所有操作都是线程安全的。
5.3 TaskManagerSlot
TaskManagerSlot 表示 TaskManager 上的一个 Slot 实例,管理 Slot 的状态和资源信息。核心字段:slotId(Slot 唯一标识)、taskManagerId(所属 TaskManager)、resourceProfile(资源配置)、state(当前状态 FREE/PENDING/ALLOCATED/RELEASED)、allocationId(分配 ID)、jobId(所属作业)。核心方法:assignPendingAllocation()(FREE→PENDING)、markAllocated()(PENDING→ALLOCATED)、releaseSlot()(释放回到 FREE)。状态转换有严格的前置条件检查,防止非法状态转换。
5.4 PendingSlotRequest
PendingSlotRequest 表示待处理的 Slot 请求,当没有 FREE Slot 时创建。核心字段:allocationId(请求唯一标识)、jobId(所属作业)、resourceProfile(资源需求)、targetSlotId(目标 Slot,如有)、creationTime(创建时间,用于超时判断)。PendingSlotRequest 等待 Slot 可用或超时。Slot 可用时,SlotManager 尝试分配;超时时,SlotManager 取消请求并通知 JobMaster。
5.5 SlotStatusSyncer
SlotStatusSyncer 是 Slot 状态同步器,定期将 SlotManager 中的 Slot 状态同步到 ResourceManager。核心功能:定期(默认几秒)遍历所有 TaskManagerSlot,收集 Slot 状态变化,通过 SlotStatusListener 通知 ResourceManager。确保 RM 和 SlotManager 的 Slot 状态一致,支持 Web UI 的 Slot 状态查询和监控。SlotStatusSyncer 在 SlotManager.start() 中启动,在 close() 中停止。
5.6 SlotManagerConfiguration
SlotManagerConfiguration 是 SlotManager 的配置类,从 Flink 配置中读取参数。核心配置:slotRequestTimeout(Slot 请求超时时间,默认5分钟)、taskManagerTimeout(TaskManager 超时时间,默认30秒)、maxNumberOfSlots(最大 Slot 数)、slotStatusSyncInterval(Slot 状态同步间隔)。这些配置控制 SlotManager 的行为和性能,生产环境需要根据作业规模和资源情况调整。
六、关键配置参数
yaml
# Slot 请求超时时间(超过该时间未分配到 Slot 则取消请求)
slotmanager.request-timeout: 5min
# TaskManager 超时时间(超过该时间未收到心跳则注销 TM)
slotmanager.taskmanager-timeout: 30s
# 最大 Slot 数(int max 表示不限制)
slotmanager.max-number-of-slots: 2147483647
# Slot 状态同步间隔
slotmanager.status-sync-interval: 5s
# JobManager 进程总内存
jobmanager.memory.process.size: 1600m
# 每个 TaskManager 的 Slot 数
taskmanager.numberOfTaskSlots: 1
# 调度器类型(adaptive:自适应调度;default:默认调度)
jobmanager.scheduler: adaptive
# 故障恢复策略(region:只重启受影响区域;full:重启整个作业)
jobmanager.execution.failover-strategy: region
关键配置说明:
slotmanager.request-timeout:Slot 请求超时时间,默认5分钟。大作业或资源紧张时可适当调大,但过大会导致作业长时间等待slotmanager.taskmanager-timeout:TaskManager 超时时间,默认30秒。网络不稳定时可适当调大,避免 TM 被误注销taskmanager.numberOfTaskSlots:每个 TaskManager 的 Slot 数,根据 TM 资源和作业并行度配置jobmanager.scheduler:调度器类型,adaptive 支持动态调整并行度,生产环境推荐jobmanager.execution.failover-strategy:故障恢复策略,region 只重启受影响区域,生产环境用 region
七、常见问题与最佳实践
7.1 常见问题
问题1:Slot 请求超时
- 原因:TaskManager 数量不足,Slot 总数不够,资源紧张,PendingSlotRequest 长时间等待
- 解决:增加 TaskManager 数量或 Slot 数,检查资源配置,调整 slotmanager.request-timeout,优化作业并行度
问题2:Slot 分配失败(TM 无响应)
- 原因:TaskManager 心跳超时,网络不通,TM 进程异常,Slot 分配请求未收到响应
- 解决:检查 TaskManager 状态和心跳,确认网络连接,查看 TM 日志,调整 slotmanager.taskmanager-timeout
问题3:Slot 泄漏(已分配不释放)
- 原因:作业异常退出,Slot 释放逻辑未执行,TaskManager 异常,Slot 状态不一致
- 解决:检查作业是否正常完成,确认 Slot 释放逻辑,查看 SlotManager 日志,重启 JobManager 清理泄漏 Slot
问题4:Slot 状态不一致
- 原因:SlotStatusSyncer 异常,ResourceManager 和 SlotManager 状态不同步,Web UI 显示异常
- 解决:检查 SlotStatusSyncer 状态,确认同步间隔配置,查看 RM 日志,重启 JobManager 恢复状态
7.2 最佳实践
1. 合理配置 Slot 数和并行度:生产环境根据 TaskManager 资源配置 numberOfTaskSlots,作业并行度不超过总 Slot 数。Slot 数过多会导致资源碎片化,过少会导致并行度不足。建议每个 Slot 配置足够的 CPU 和内存。
2. 配置合适的超时时间:slotmanager.request-timeout 根据作业规模和资源情况配置,大作业可适当调大(10-15分钟),小作业保持默认5分钟。slotmanager.taskmanager-timeout 根据网络稳定性配置,稳定网络保持30秒,不稳定网络可调大到60秒。
3. 监控 Slot 使用情况:关注 SlotManager 的 FREE/PENDING/ALLOCATED Slot 数、PendingSlotRequest 队列长度、Slot 请求超时次数、Slot 分配成功率。配置 Prometheus 指标上报和告警,及时发现资源不足和 Slot 泄漏。
4. 使用 adaptive 调度器:生产环境使用 jobmanager.scheduler: adaptive,支持动态调整并行度,根据可用 Slot 数自动调整作业并行度,提高资源利用率和作业稳定性。
5. 避免 Slot 泄漏:确保作业正常完成或取消时 Slot 被正确释放。使用 region 故障恢复策略,减少故障恢复时的 Slot 重新分配。定期检查 Slot 状态,发现泄漏及时处理。
6. 优化 Slot 分配策略:大作业优先分配,小作业快速分配。根据资源需求匹配 Slot,避免大资源需求占用小 Slot。使用 Slot Sharing 提高资源利用率,但注意隔离性要求。
八、总结
Flink SlotManager 启动流程源码深度剖析要点回顾:
第一,SlotManager 整体架构是理解的基础。SlotManager 运行在 ResourceManager 进程内部,是 Flink 集群资源管理的核心。内部四大核心组件:TaskManagerSlot(Slot 实例,管理状态)、PendingSlotRequest(待处理请求,等待和超时)、SlotStatusSyncer(状态同步器)、SlotManagerConfiguration(配置参数)。Slot 有四种状态:FREE(空闲可用)、PENDING(分配中)、ALLOCATED(已分配)、RELEASED(已释放)。
第二,ResourceManager 启动与 SlotManager 启动是入口。ResourceManager.onStart() 中第一个启动的组件就是 SlotManager,因为后续的 TaskManager 注册和 Slot 分配都依赖它。ResourceManager 成为 Leader 后调用 slotManager.setLeaderSessionId(),SlotManager 开始正常工作。SlotManager 在 ResourceManagerFactory 中创建,默认实现是 SlotManagerImpl。
第三,SlotManager 内部启动流程是六步:构造函数初始化(taskManagerSlots、pendingSlotRequests)→ start() 启动 → 启动 SlotStatusSyncer → 注册 Slot 状态监听器 → 启动超时检查 → 等待 Slot 请求。超时检查是重要机制,PendingSlotRequest 超过配置时间(默认5分钟)未分配则取消并通知 JobMaster。
第四,Slot 分配机制与状态机是核心。Slot 分配六步:接收请求 → 查找 FREE Slot → 标记 PENDING → 通知 TM 分配 → 标记 ALLOCATED → 返回成功。无 FREE Slot 时创建 PendingSlotRequest 等待,同时通知 RM 申请新资源。Slot 状态转换有严格前置条件:FREE→PENDING(分配请求)、PENDING→ALLOCATED(TM 确认)、ALLOCATED/PENDING→RELEASED→FREE(释放)。TaskManager 注册时创建 TaskManagerSlot,初始为 FREE,注册后尝试分配等待中的请求。
第五,核心类源码是理解实现的关键。SlotManager 接口定义核心方法,SlotManagerImpl 是默认实现(维护两个核心数据结构),TaskManagerSlot 管理 Slot 状态和资源,PendingSlotRequest 管理等待请求和超时,SlotStatusSyncer 定期同步状态,SlotManagerConfiguration 管理配置参数。
理解 Flink SlotManager,不仅能帮助排查 Slot 请求超时、Slot 分配失败、Slot 泄漏、Slot 状态不一致等常见问题,更能体会到 Flink 资源管理的分层设计------JobMaster 的 SlotPool 负责作业级 Slot 管理,ResourceManager 负责集群级资源协调,SlotManager 负责 Slot 分配和状态管理,TaskManager 负责 Slot 资源提供。四者通过 requestSlot 和 allocateSlot 机制协作,构成了 Flink 集群完整的资源分配和管理体系。