- Published on
记一次 YARN 集群扩容引发的“幽灵”宕机事件
- Authors

- Name
- Charles Chen
在大数据高并发场景的深水区游走,往往会遇到一些让人摸不着头脑的灵异事件。
最近在生产环境中,我们的 Flink 实时计算任务就遭遇了一场典型的“俄罗斯轮盘赌”:有的任务提交后行云流水,有的任务却如泥牛入海,AM(Application Master)活着,却永远等不来它的 TaskManager。
这篇文章将复盘这次幽灵宕机事件,从表象一路扒到分布式系统的底层架构设计,聊聊配置漂移(Configuration Drift)带来的深远影响。
诡异的案发现场
在一次日常的任务调度监控中,我们发现海豚调度(DolphinScheduler)中的部分 Flink Shell 任务出现了随机性卡死。
主要症状如下:
- 任务假死: 任务状态处于
RUNNING,但实际上毫无进展。 - 资源占着不拉屎: 观察 YARN 队列,发现对应队列的
Num Active Applications增加了,AM 成功分配到了 1 vCore 和 1GB 内存,但整个集群明明有几百个 Core 的盈余,Task 资源却一点都分不下来。 - 薛定谔的成功率: 同样的任务,重跑一次可能就成功了;再跑一次,可能又卡死了。毫无规律可言。
起初,这种症状极容易把人引向“资源队列配额(Queue Capacity)不足”或“容器最大分配限制(Max Container Allocation)阻断”的误区。但经过对 fair-scheduler.xml 的排查,父子队列配比健康,单任务申请的内存也远未触及 12GB 的硬性天花板。
问题,显然藏在更深的地方。
抽丝剥茧:AM 为什么变成了“瞎子”?
架构师的直觉告诉我们,看监控不如看底层的运行日志。在翻阅了那个卡死长达 5 分钟的 Flink 任务 jobmanager.log 后,一行致命的报错浮出水面:
Plaintext
Retrying connect to server: 0.0.0.0/0.0.0.0:8030. Already tried 9 time(s)...
java.net.ConnectException: Your endpoint configuration is wrong...
接着,任务在重试了 300000 毫秒(5 分钟)后,抛出了终极绝望: NoResourceAvailableException: Slot request bulk is not fulfillable! Could not allocate the required slot within slot request timeout
破案了!
Flink 的 Application Master 并不是没有资源,而是它找不到 ResourceManager (RM) 在哪里。由于迷失了方向,它只能退而求其次,使用了 Hadoop 的兜底默认地址:试图去连接自己本机的 0.0.0.0:8030 端口。这台普通的计算节点上当然没有 RM,所以它只能一遍遍重试,直到把自己饿死。
架构级归因:可怕的“配置漂移”
但为什么这个问题是随机发生的?结合近期我们刚刚对 CDH 集群进行过计算节点扩容的背景,整个逻辑闭环彻底打通。
在大数据分布式架构中,一次完整的 Flink on YARN 任务提交分为两步:
- 客户端提交(海豚调度节点): 海豚所在节点环境完备,成功向真实的 RM 申请到了一个 Container,用于启动 AM。
- AM 随机降落(NodeManager 节点): YARN 随机挑选了一台空闲机器启动这个 AM。
俄罗斯轮盘赌的扳机就在这里被扣动:
- 如果 AM 碰巧降落在了老节点,老节点的
/etc/hadoop/conf下有完整的yarn-site.xml,AM 顺利读取配置,找到高可用的 RM 地址,任务成功。 - 如果 AM 不幸降落在了新增的节点,由于我们在扩容时没有将 Hadoop 的核心配置文件(以及
/etc/hosts解析)同步过去,新节点存在严重的配置漂移(Configuration Drift)。AM 在本地目录下找不到 RM 地址,瞬间变成“瞎子”,导致任务流产。
解决之道与深度反思
立竿见影的修复: 从任意一台正常的老节点,将 /etc/hadoop/conf.cloudera.yarn 目录下的核心配置文件(core-site.xml, hdfs-site.xml, yarn-site.xml)以及 /etc/hosts 完整同步到所有新增节点,问题瞬间灰飞烟灭。
留给分布式架构设计的反思:
- 警惕基础设施即代码(IaC)的缺失: 靠人力手动执行
scp同步配置,在节点规模突破百台级别时,是极其危险且不可持续的。对于现代大数据集群,必须引入 Ansible、Terraform 等工具,或者全面拥抱云原生的 K8s 架构(如 Flink Native K8s),将配置通过 ConfigMap 全局下发,从根本上杜绝“有的机器有配置,有的机器没配置”的薛定谔状态。 - 规范日志与底层解耦: 在排查期间,我们还顺手在日志里发现了一个有趣的彩蛋——底层虽然已经完成了从 TiDB 到 OceanBase 的主从切换,但业务侧的
System.out依然硬编码着 TiDB 的字样。追求极致的系统,不仅要做到高可用,更要做到监控和日志的所见即所得。
结语
技术永远在演进,从早期的硬编码配置,到 YARN 的 Node Labels 调度,再到如今大势所趋的云原生 Vibe Coding 理念。每一次排障,都不应只是重启和同步文件,而是一次对现有系统架构脆弱性的深度审视。
敬畏每一行日志,保持对底层链路的好奇心,这是每一位架构师的必修课。