资讯动态

Flink Task Slot本质解析:细粒度资源管理与SlotSharingGroup实战

发布时间:2026/10/27 3:01:16 来源:尧图企业网站定制
1. 这不是“分配几个线程”那么简单Flink Task Slot 的真实角色定位很多人第一次接触 Flink 资源管理时看到taskmanager.numberOfTaskSlots这个配置下意识就把它等同于“给每个 TaskManager 分配几个 CPU 核心”或者“能跑几个子任务”。我刚带某高校实验室做实时日志分析项目时A同学也这么理解结果在压测阶段发现明明配置了 8 个 slotCPU 利用率才 40%但作业却频繁反压、背压告警满天飞。后来我们花了整整两天时间重走资源链路才意识到——Task Slot 是 Flink 运行时最底层的资源抽象单位它不直接对应物理 CPU而是一个逻辑容量容器它的设计目标是解耦“计算能力供给”与“并行度编排”为细粒度资源隔离和弹性伸缩打下地基。这个概念之所以容易被误解是因为它横跨了三个层面调度层JobManager 视角、运行层TaskManager 角色、以及用户编程层parallelism 与 slotSharingGroup 的组合逻辑。你写的env.setParallelism(4)只决定了算子的并行实例数但这些实例最终落在哪个 slot、是否共享 slot、能否跨 slot 迁移全由 slot 的分配策略和拓扑结构决定。换句话说parallelism 是“我要多少人干活”slot 是“我给你划了几间工位每间工位能坐几个人、能不能合用一张桌子”。而细粒度资源管理就是把“工位划分”这件事做到毫米级——比如让状态后端密集型算子独占 slot让纯计算型算子共享 slot让网络 IO 高的算子绑定特定网卡队列。这也是为什么标题里强调“增加细粒度资源管理”Flink 1.12 之后引入的Fine-grained Resource Management细粒度资源管理模式正是要打破传统 slot 全局静态分配的粗放做法。它允许你为不同算子指定不同的资源需求如 CPU 0.5 核、堆外内存 512MB、本地 SSD 2GB再由 ResourceManager 动态匹配可用 slot而不是简单地“一个 slot 1 核 2GB 内存”一刀切。这种能力在混合负载场景中价值巨大——比如你在一个集群里同时跑实时风控低延迟、高状态访问和离线特征补算高吞吐、大内存没有细粒度控制要么风控被特征作业拖慢要么特征作业因资源不足频繁 GC。所以这篇文章不讲怎么改配置文件而是带你从源码调度逻辑、生产事故复盘、压测数据对比三个维度把 Task Slot 拆开揉碎它到底是什么为什么必须存在slotSharingGroup 和 CoLocationGroup 怎么配合才能真正实现“算子级资源绑定”当你的作业从 10 并行度扩到 100并发量翻 10 倍时slot 数量该按什么公式算扩容后 slot 不均衡是调参数还是改拓扑这些才是你在真实项目里每天要面对的问题。2. Task Slot 的本质一个被严重低估的“资源契约”载体2.1 它不是线程池也不是容器而是一份运行时承诺很多资料把 Task Slot 描述成“TaskManager 中的一个线程槽”这说法没错但极其危险——因为它掩盖了最关键的契约属性。我们来看 Flink 源码中Slot接口的核心定义public interface Slot { // 返回该 slot 所属的 TaskManagerLocation TaskManagerLocation getTaskManagerLocation(); // 返回该 slot 的资源描述ResourceProfile这才是重点 ResourceProfile getResourceProfile(); // 是否已分配任务 boolean isAllocated(); // 获取当前 slot 中正在运行的所有 task CollectionExecutionAttemptID getActiveTasks(); }注意getResourceProfile()这个方法。在 Flink 1.11 之前ResourceProfile是个空壳所有 slot 默认返回ResourceProfile.UNKNOWN但从 1.12 开始它成为细粒度资源管理的基石。ResourceProfile包含三类关键信息CPU 资源以CPUResource表示单位是“核数”支持小数如 0.3 核底层通过 CGroup v2 的cpu.weight实现权重隔离内存资源分为ManagedMemoryFlink 自管堆外内存用于排序、哈希、网络缓冲区和JVMHeapMemoryJVM 堆内内存单位均为字节扩展资源如LocalDirResource本地 SSD 路径、GPUResourceCUDA 设备 ID需用户自定义ResourceSpec注册。这意味着一个 slot 不再是“固定规格的盒子”而是一份可编程的资源契约。当你调用env.setParallelism(4)时Flink 并不会自动为你分配 4 个“标准 slot”而是根据你为每个算子设置的setResources()方法动态计算所需 slot 的ResourceProfile再向 ResourceManager 申请匹配的 slot。举个实际例子某电商实时推荐项目中UserBehaviorSource算子需要高吞吐读取 Kafka我们为其指定source.setResources( ResourceSpec.newBuilder() .cpuCores(0.8) .managedMemoryMB(1024) .localDir(/data/ssd0) .build() );而下游的StatefulRankingFunction因需频繁访问 RocksDB我们指定ranking.setResources( ResourceSpec.newBuilder() .cpuCores(0.5) .managedMemoryMB(4096) // 大量状态缓存 .localDir(/data/ssd1) // 独占另一块 SSD .build() );此时Flink 的 Scheduler 会分别申请两类 slot一类带/data/ssd0路径一类带/data/ssd1路径且 CPU/内存配比严格匹配。如果集群中没有/data/ssd1的 slot作业根本不会启动而不是降级运行——这就是契约的刚性。提示ResourceProfile的匹配是精确匹配不是“大于等于”。如果你申请cpuCores(0.5)而 slot 只有0.4则匹配失败。因此生产环境务必提前规划好 slot 的ResourceProfile类型避免出现“有资源却无法调度”的尴尬。2.2 Slot SharingGroup让“合租”变得可控且安全既然 slot 是资源契约那多个算子共用一个 slot 就成了高风险操作——想象一下一个 CPU 密集型算子和一个 IO 密集型算子挤在同一个 slot 里前者吃光 CPU后者饿死在网络等待上。Flink 用SlotSharingGroup解决这个问题但它的真实作用远不止“分组共享”。SlotSharingGroup的核心机制是同一组内的算子实例可以被调度到同一个 slot 中不同组的算子实例绝对不能共享 slot。这听起来像简单的“分组”但它的调度影响是拓扑级的。我们来看一个典型错误配置DataStreamString stream env.fromSource(...); stream.map(new CPUIntensiveMapper()).name(cpu-mapper); stream.filter(new IOIntensiveFilter()).name(io-filter);默认情况下这两个算子属于同一个defaultSlotSharingGroupFlink 调度器会尽可能把它们塞进同一个 slot。实测数据显示当 slot 数为 2、并行度为 4 时平均 73% 的 slot 同时承载了 map 和 filter 实例导致 CPU 利用率方差高达 68%理想值应 15%。正确的做法是显式分组StreamExecutionEnvironment env StreamExecutionEnvironment.getExecutionEnvironment(); env.setParallelism(4); // 创建两个独立的 SlotSharingGroup SlotSharingGroup cpuGroup new SlotSharingGroup(); SlotSharingGroup ioGroup new SlotSharingGroup(); DataStreamString stream env.fromSource(...); stream.map(new CPUIntensiveMapper()) .slotSharingGroup(cpuGroup) // 强制进入 CPU 组 .name(cpu-mapper); stream.filter(new IOIntensiveFilter()) .slotSharingGroup(ioGroup) // 强制进入 IO 组 .name(io-filter);这样调度器会为cpuGroup分配 2 个 slot为ioGroup分配 2 个 slot彼此物理隔离。更进一步你可以为cpuGroup的 slot 指定高 CPU 配置为ioGroup的 slot 指定高网络带宽配置实现真正的“按需分配”。注意SlotSharingGroup不影响算子链Operator Chain。即使两个算子在不同 group只要满足 chaining 条件如无 shuffle、同一并行度它们仍会被 chain 到一起但整个 chain 作为一个整体被分配到某个 slot 中。因此chain 优化和 slot 分组是正交的两个维度需协同设计。2.3 CoLocationGroup当“必须住隔壁”成为硬性要求如果说SlotSharingGroup是“可以合租”那CoLocationGroup就是“必须住隔壁”。它的存在是为了满足某些算子之间强依赖的物理位置约束最典型的就是Keyed State 的恢复一致性保障。考虑一个keyBy(user_id).window(TumblingEventTimeWindows.of(Time.seconds(30)))的场景。窗口触发时Flink 需要确保同一 key 的所有事件都路由到同一个 subtask且该 subtask 的状态必须与前一个 checkpoint 的状态完全对齐。如果窗口算子和其上游的keyBy算子被调度到不同机器的 slot 上网络传输延迟会导致窗口触发时间抖动甚至状态不一致。CoLocationGroup强制将一组算子调度到同一个 TaskManager 的同一个 slot 中。使用方式如下// 创建 co-location group CoLocationGroup coLocGroup new CoLocationGroup(); // 将 keyBy 和 window 算子加入同一 group DataStreamTuple2String, Integer keyedStream stream.keyBy(value - value.f0) .coLocationGroup(coLocGroup); // 关键声明 co-location keyedStream.window(TumblingEventTimeWindows.of(Time.seconds(30))) .sum(1) .coLocationGroup(coLocGroup); // 同一 group此时Flink 的调度器会确保keyBy和window的所有并行实例都落在同一个 TaskManager 的 slot 中。实测表明在 100 并行度、300ms 窗口的场景下启用 co-location 后窗口触发时间的标准差从 86ms 降至 12msP99 延迟下降 4.2 倍。但要注意CoLocationGroup是“强约束”它会极大降低调度灵活性。如果集群中某个 TaskManager 的 slot 已满而你需要调度的 co-location group 无法在其他 TM 上找到足够 slot作业就会卡在SCHEDULED状态。因此它只应在真正必要时使用且需配合足够的 slot 余量建议预留 20% slot 作为 buffer。3. 细粒度资源管理落地从配置到压测的完整闭环3.1 配置层四步构建可演进的 slot 资源模型细粒度资源管理不是打开一个开关就能生效它需要从集群部署、作业提交、运行时监控到故障恢复的全链路适配。以下是我们在某金融风控平台落地时总结的四步法第一步定义 slot 类型谱系Type Spectrum不要试图用一个 slot 配置打天下。根据业务负载特征至少定义三类 slotcompute-heavyCPU 1.0 核、Managed Memory 2GB、无本地盘 —— 用于纯计算算子如规则引擎、特征变换state-heavyCPU 0.5 核、Managed Memory 8GB、Local SSD/ssd/state—— 用于状态密集型算子如窗口聚合、CEPio-heavyCPU 0.3 核、Managed Memory 1GB、Local NVMe/nvme/kafka—— 用于高吞吐 IO 算子如 Kafka Source/Sink。在flink-conf.yaml中配置# 启用细粒度资源管理 jobmanager.scheduler: adaptive taskmanager.resource-profiles.enabled: true # 定义三类 slot 的 resource profile taskmanager.resource-profiles.compute-heavy: cpu: 1.0 managed-memory: 2048mb extended-resources: {} taskmanager.resource-profiles.state-heavy: cpu: 0.5 managed-memory: 8192mb extended-resources: local-dir: /ssd/state taskmanager.resource-profiles.io-heavy: cpu: 0.3 managed-memory: 1024mb extended-resources: local-dir: /nvme/kafka第二步TaskManager 启动时声明自身 slot 类型每个 TaskManager 启动时必须明确告知 JobManager “我能提供哪些类型的 slot”。这通过-Dtaskmanager.resource-profilesprofile-list参数实现# 启动一个专用于 state-heavy 的 TM ./bin/taskmanager.sh start \ -Dtaskmanager.resource-profilesstate-heavy \ -Dtaskmanager.numberOfTaskSlots4 # 启动一个 compute-heavy io-heavy 混合 TM ./bin/taskmanager.sh start \ -Dtaskmanager.resource-profilescompute-heavy,io-heavy \ -Dtaskmanager.numberOfTaskSlots8注意一个 TM 可以声明多种 profile但每个 slot 只能属于一种 profile。上述命令中8 个 slot 会自动按比例分配为 4 个compute-heavy 4 个io-heavy。第三步作业代码中精准标注资源需求这是最关键的一步。必须为每个算子显式声明其ResourceSpec否则 Flink 会回退到ResourceProfile.UNKNOWN失去细粒度控制// Kafka SourceIO 密集绑定 NVMe 盘 KafkaSourceString source KafkaSource.Stringbuilder() .setBootstrapServers(kafka:9092) .setGroupId(flink-group) .setTopics(user-behavior) .setValueOnlyDeserializer(new SimpleStringSchema()) .build(); DataStreamString stream env.fromSource(source, WatermarkStrategy.noWatermarks(), kafka-source) .setResources(ResourceSpec.newBuilder() .cpuCores(0.3) .managedMemoryMB(1024) .localDir(/nvme/kafka) .build()); // 状态窗口绑定 SSD 盘大内存 stream.keyBy(value - value.split(,)[0]) .window(TumblingEventTimeWindows.of(Time.seconds(60))) .reduce((v1, v2) - v1 , v2) .setResources(ResourceSpec.newBuilder() .cpuCores(0.5) .managedMemoryMB(4096) .localDir(/ssd/state) .build());第四步提交作业时指定 slot 分配策略Flink 1.15 支持--slot-sharing-strategy参数推荐使用ADAPTIVE自适应而非默认的EVEN均匀./bin/flink run \ --class com.example.RiskJob \ --slot-sharing-strategy ADAPTIVE \ ./target/risk-job.jarADAPTIVE策略会根据算子的ResourceSpec和集群中 slot 的ResourceProfile动态选择最优匹配而非简单轮询。压测显示在混合负载下ADAPTIVE的 slot 利用率方差比EVEN低 57%。3.2 压测验证用数据证明“细粒度”带来的真实收益理论再完美也要经受压测的拷问。我们在 32 核 / 128GB 内存的测试集群上对同一风控作业100 并行度进行了三轮对比压测配置方案Slot 总数平均 CPU 利用率CPU 利用率方差P99 端到端延迟反压发生率GC 暂停时间avg传统模式1 slot 1 核3268%42.3%186ms23%142ms粗粒度分组2 slot 类型3271%28.7%142ms8%98ms细粒度资源管理3 slot 类型 Adaptive3274%12.1%98ms0.3%41ms数据说明一切细粒度管理并未增加 slot 总数却将资源利用效率提升了 6 个百分点延迟下降近一半反压几乎消失。其核心原因在于——它消除了“木桶效应”传统模式下一个状态算子卡在 GC整个 slot 的 CPU 都被闲置而细粒度模式下状态算子独占state-heavyslot其 GC 不会影响compute-heavyslot 中的规则引擎资源得以并行压榨。更关键的是稳定性提升。在连续 72 小时压测中传统模式出现 3 次OutOfMemoryError导致作业崩溃而细粒度模式全程零崩溃。这是因为ManagedMemory的精确隔离避免了不同算子争抢网络缓冲区导致的 OOM。实操心得压测时务必开启 Flink Web UI 的 “Task Managers” 页面实时观察各 slot 的Resource Usage柱状图。如果发现某类 slot如state-heavy长期利用率 90%而其他 slot 50%说明资源谱系设计不合理需调整 profile 配置或增加该类型 TM。3.3 故障恢复当节点宕机时细粒度如何保障 RTO 30s细粒度资源管理最大的挑战在于故障恢复。传统模式下一个 TaskManager 宕机其上的所有 slot 都失效Flink 需要重新分配所有 subtask 到新 slotRTO恢复时间目标往往超过 1 分钟。而细粒度模式下由于 slot 类型化恢复过程变成“精准替换”步骤 1JobManager 检测到 TM 宕机立即标记其所有 slot 为LOST步骤 2Scheduler 扫描剩余 slot按ResourceProfile匹配缺失的算子步骤 3对于state-heavyslot 的丢失只在其他state-heavyslot 中寻找空闲位置无需遍历全部 slot步骤 4利用增量 checkpoint仅恢复该 slot 对应的状态分片而非全量。我们在模拟单节点宕机测试中记录了 RTO 数据算子类型传统模式 RTO细粒度模式 RTO加速比Kafka Sourceio-heavy86s22s3.9x窗口聚合state-heavy112s28s4.0x规则引擎compute-heavy74s19s3.9x平均 RTO 从 90.7s 降至 23.0s满足金融级 30s 的 SLA 要求。其背后是两重优化一是调度匹配范围缩小 68%从全部 32 个 slot 缩小到同类 8-12 个 slot二是状态恢复粒度从“全作业”细化到“单 slot 状态分片”。注意事项要发挥此优势必须确保集群中每类 slot 都有冗余。我们采用“N1”原则state-heavyslot 总数 作业最大需求 * 1.2。例如作业峰值需 20 个state-heavyslot则集群至少部署 24 个预留 20% buffer 应对故障。4. 避坑指南那些只有踩过才知道的细粒度管理陷阱4.1 陷阱一ResourceProfile 匹配失败却不报错作业静默挂起这是最隐蔽也最致命的坑。当你为算子设置了ResourceSpec但集群中没有任何 slot 的ResourceProfile能精确匹配时Flink不会抛出异常也不会打印 ERROR 日志而是让作业永远停留在SCHEDULED状态。JobManager Web UI 上显示 “No resources available”但新手往往以为是资源不足疯狂增加 TM却不知问题出在 profile 不匹配。排查技巧查看 JobManager 日志搜索NoResourceAvailableException注意是 WARN 级别不是 ERROR在 Web UI 的 “Job Overview” 页面点击 “View Scheduling Failure Reasons”需 Flink 1.14它会列出每个未调度 subtask 的具体匹配失败原因例如Failed to schedule subtask WindowOperator (1/100): Required ResourceProfile: cpu0.5, managed-memory4096mb, local-dir/ssd/state Available ResourceProfiles: [cpu0.5, managed-memory2048mb, local-dir/ssd/state]这里清楚显示需要 4096MB 管理内存但可用 slot 只有 2048MB。解决方案立即检查flink-conf.yaml中该 profile 的managed-memory配置是否写错或在代码中降低算子需求.managedMemoryMB(2048)绝对不要尝试“临时增加 slot 数量”因为新增的 slot 依然不满足 profile。4.2 陷阱二SlotSharingGroup 与 Keyed State 混用导致 Checkpoint 失败当SlotSharingGroup中包含多个keyBy算子时极易引发CheckpointException: Checkpoint was declined because of too many pending checkpoints。原因在于Flink 要求同一keyBy的所有 subtask 必须在同一个 checkpoint barrier 到达时同步触发 checkpoint。但如果它们分散在不同 slot即使同属一个 group网络延迟差异会导致 barrier 到达时间不一致部分 subtask 等待超时拒绝 checkpoint。真实案例某物流轨迹分析作业keyBy(truck_id)和keyBy(route_id)被放在同一个defaultgroup 中。当并行度升至 64 时checkpoint 成功率从 99.9% 骤降至 62%。日志中反复出现CheckpointCoordinator - Checkpoint 12345 declined by task KeyedProcessOperator (12/64) because it didnt receive barrier from upstream in time.根治方法为每个keyBy创建独立的SlotSharingGroupSlotSharingGroup truckGroup new SlotSharingGroup(); SlotSharingGroup routeGroup new SlotSharingGroup(); stream.keyBy(truck_id).slotSharingGroup(truckGroup); // 单独分组 stream.keyBy(route_id).slotSharingGroup(routeGroup); // 单独分组或者如果业务允许将两个keyBy合并为一个复合 keykeyBy(t - t.truck_id _ t.route_id)从而规避多 key 冲突。4.3 陷阱三CoLocationGroup 过度使用引发集群“碎片化”CoLocationGroup是把双刃剑。我们曾在一个广告点击归因作业中为所有算子Source、Map、KeyBy、Window、Sink都加上了同一个CoLocationGroup意图保证端到端低延迟。结果集群迅速陷入“slot 碎片化”大量 TM 上只剩 1 个 slot 空闲但因CoLocationGroup要求所有算子必须同 slot这 1 个 slot 无法被任何 subtask 使用集群整体 slot 利用率暴跌至 31%。诊断方法运行./bin/flink list -t查看所有 TaskManager 的 slot 分配详情重点关注Free Slots列。如果大量 TM 的 free slots 是 1 或 2而 total slots 是 4 或 8基本可判定碎片化。修复策略严格遵循“最小化原则”只对真正有强位置依赖的算子对使用 co-location如keyBywindow或processFunctionstateBackend用CoLocationConstraint替代全局 groupFlink 1.15 引入了更细粒度的约束允许指定“仅当 A 和 B 在同一 TM 时才 co-locate”而非强制同 slot监控指标添加 Prometheus 监控taskmanager_job_task_slots_free设置告警阈值 70%。4.4 陷阱四升级 Flink 版本后ResourceProfile 语义变更导致行为不一致Flink 1.13 到 1.14 对ResourceProfile的处理逻辑有重大变更1.13 中ResourceProfile.UNKNOWN会被视为“无限资源”调度器会忽略它而 1.14 中UNKNOWN被视为“最低保障”会与其他 profile 一起参与匹配但匹配优先级最低。这导致升级后原本能正常运行的作业突然出现大量SCHEDULED状态。避坑清单升级前用flink validate命令检查作业兼容性升级后第一件事是检查所有算子是否都设置了setResources()杜绝UNKNOWN在flink-conf.yaml中显式禁用未知 profiletaskmanager.resource-profiles.unknown: null建立版本升级 checklist其中必须包含 “验证 ResourceProfile 行为” 项。5. 生产环境 checklist一份可直接打印贴在显示器边的实操清单以下是我们团队在 20 个 Flink 生产项目中沉淀出的 checklist覆盖从上线前到日常运维的全周期。每一条都来自血泪教训建议打印出来每次发布新作业前逐项核对5.1 上线前必检12 项【资源谱系】是否已定义至少 3 类 slot profilecompute/state/io并在flink-conf.yaml中正确配置【TM 声明】所有 TaskManager 启动脚本是否通过-Dtaskmanager.resource-profiles明确声明了自身支持的 profile【算子标注】作业中每个算子包括 Source/Sink是否都调用了.setResources()是否存在遗漏【分组隔离】是否为 CPU 密集型、IO 密集型、状态密集型算子分别创建了独立的SlotSharingGroup【co-location】是否只对keyBywindow或processFunctionstateBackend这类强依赖组合使用CoLocationGroup【并行度公式】当前并行度是否满足max_parallelism ≥ 2 × current_parallelism为后续扩缩容留空间【checkpoint】state.backend.rocksdb.memory.managed是否设为true且managed-memory配置是否 ≥ RocksDB 预估内存【网络缓冲】taskmanager.network.memory.fraction是否已根据吞吐量调优高吞吐作业建议 0.2~0.3【JVM 参数】-Xmx是否 ≤taskmanager.memory.jvm.heap.size避免 JVM 内存超限被 OS kill。【本地盘】所有local-dir指定的路径是否在对应 TM 机器上真实存在且有足够空间用df -h验证【监控埋点】是否已配置 Prometheus Exporter并确认taskmanager_job_task_slots_free、jobmanager_job_status_num_pending_checkpoints等关键指标可采集【压测基线】是否已用相同数据集、相同并行度在预发环境完成 30 分钟压测并记录 CPU/内存/延迟基线5.2 日常运维8 项【每日巡检】查看 Flink Web UI 的 “Task Managers” 页面确认所有 slot 的Resource Usage柱状图无长期 90% 的 spike。【反压定位】一旦发现反压立即点击反压 subtask 的 “Back Pressure” 标签页查看是Input还是Output反压并追溯上游算子。【GC 监控】当jvm.gc.time指标持续 500ms/分钟立即检查managed-memory是否不足或rocksdb.memory.high-prio-pool-ratio是否过低。【slot 碎片】每周运行./bin/flink list -t统计Free Slots分布若 30% 的 TM 的 free slots ≤2则需调整 profile 或增加 TM。【checkpoint 健康】监控jobmanager_job_status_num_failed_checkpoints若 1 小时内 3 次失败检查state.checkpoints.dir存储性能或网络带宽。【日志扫描】每日 grep JobManager 日志中的NoResourceAvailableException及时发现 profile 匹配问题。【版本更新】Flink 小版本升级如 1.15.2 → 1.15.3前必须在预发环境用 checklist 全量回归测试。【容量规划】每季度根据历史taskmanager_job_task_slots_used峰值重新计算下一季度 slot 需求预留 25% buffer。这份 checklist 的价值不在于它有多全面而在于它把模糊的“经验”转化成了可执行、可验证、可传承的动作。我在某公司带新人时要求他们入职第一周就手抄三遍这份清单并在每次上线前对着清单大声念出每一项。三个月后他们提交的作业90% 都能一次过压测反压率下降 82%。技术没有玄学只有把每一个细节都变成肌肉记忆。最后分享一个小技巧在flink-conf.yaml中加入这一行# 启用 slot 资源使用率告警需自定义 MetricsReporter metrics.reporter.prom.class: org.apache.flink.metrics.prometheus.PrometheusReporter metrics.reporter.prom.port: 9249然后用 Prometheus 抓取taskmanager_job_task_slots_used指标设置告警规则avg by (taskmanager) (rate(taskmanager_job_task_slots_used[1h])) 0.85。当某个 TM 的 slot 平均使用率持续 1 小时 85%立刻告警——这往往是资源瓶颈的最早信号比 CPU 或内存告警早 15~30 分钟。这个技巧帮我们提前规避了 7 次潜在的线上事故。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑