Spark UI实战:从Stage与Executor指标到数据倾斜与参数调优

发布时间:2026/9/29 16:30:14

Spark UI实战:从Stage与Executor指标到数据倾斜与参数调优 1. 从点错页面到看懂全局Spark UI的层级关系先理清很多人第一次点开Spark UI习惯性先看最显眼的Jobs列表发现作业失败或卡住马上就慌。但UI这玩意儿本质上是一套按执行粒度层层嵌套的档案系统你跳过了外层直接看内层等于看一本只有目录的书——信息都在就是串不起来。Spark UI的逻辑层级是固定的一套Jobs作业 → Stages阶段 → Tasks任务外加Executors执行器和Storage存储两个辅助视角。一个Job由一次Action比如count()、save()触发Job里可能包含多个StageStage之间以Shuffle为边界切开每个Stage里又根据数据分区拆出很多Task。UI的主页默认按Job倒序排列点击一条Job记录你才能看到它包含的Stage列表再点进某个Stage才能看Task级别的明细。这里有个新人最容易犯的错看到一条Job整体变红就以为完蛋了直接从头开始调参数。正确做法是先点进Job详情看每个Stage的耗时占比。大多数实际场景里一个Job的慢不是所有Stage都慢而是某一个Stage拖了后腿——数据倾斜通常发生在Shuffle之后的聚合Stage资源不足通常表现为所有Task运行时间超长。你只有先定位到是哪个Stage出了问题后面调参数才有意义。还有个小细节UI顶部通常有SQL这个入口但它的入站条件是有Spark SQL或DataFrame操作被触发过。你跑纯RDD操作时这个标签页就是冷的别在那里翻半天。按我自己的习惯排查一个作业先看三个地方就够了Executors页确认资源是不是比申请时缩水了Stage页确认是不是存在明显的Task耗时不均SQL页确认物理执行计划有没有和预料中差别很大。这三步看完80%的锅基本能定位。2. Executor标签页的读数方法把内存参数和界面数字对上号Executors页面是所有性能排查的第一现场因为它展示的是真实运行时的资源占用不是你在提交参数里写的理想状态。页面上每行代表一个Executor列的排序可以点表头调整最关键的列是这三项RDD Blocks、Storage Memory、Disk Used。先说内存。你在提交脚本时写的spark.executor.memory配置的是JVM堆内内存但UI里显示的Storage Memory其实是堆内加堆外两部分加起来的结果。Spark在初始化时会从executor内存里划出一块专门的区域给RDD缓存和Shuffle聚合用大小由spark.memory.fraction控制默认0.6这0.6又按spark.memory.storageFraction拆成执行内存和存储内存默认0.5对0.5。所以你看到某个Executor的Storage Memory一直很满不要第一反应就觉得是缓存数据太多先check一下是不是Shuffle期间的聚合数据也占用了这块区域——执行内存用完是会往存储内存区借的这俩是动态抢占关系。再一个容易被忽略的指标是GC Time。如果你看到某个Executor的GC时间飙升到几分钟说明堆内压力极大——通常是spark.executor.memory给得不够对象频繁创建和回收。这时候去翻这个Executor的日志多半能看到规律的Full GC记录。很多人舍不得加内存总觉得代码优化一下就行但实际上如果数据量级的Shuffle确实摆在那该给的内存跑不掉。不过加内存也不是无脑加经常见到spark.executor.memory8g配着spark.executor.cores8的配置一个executor开了8个核这其实是把内存分给了8个并发任务单个任务能用的还是那一丁点。合理配比通常是cores2、memory4g~6g保证单核能吃到2~3GB内存这个比例在绝大多数集群上都不会太离谱。还有Disk这一列以及与之相关的Shuffle Spill。SQL执行时如果内存缓冲不够排序和聚合的数据会溢写磁盘这在页面上的体现就是当前任务的Shuffle Spill (Memory)和Shuffle Spill (Disk)两列都有值。如果Disk的值远大于Memory说明内存规划严重不足执行内存在还没读完数据时就被打满了系统只能把中间结果落盘大量I/O自然拖慢作业。这时候除了调大executor内存也可以考虑调整spark.sql.shuffle.partitions——如果这个参数设置得过大每个分区的数据量太小反而管理开销大设置得过小单分区数据量过大又容易溢写。实际执行计划里单个Reduce分区的数据量控制在128MB~256MB左右是我个人实测比较稳的一个区间。3. Stage页的“数据倾斜CT机”三个表象定位一个病根你可以把Stage详情页想象成一张分布式系统的CT片子Task列表里的每一行都是一个分区上的局部快照。倾斜的本质很简单某个分区的数据量远大于均值表现出来就是它的Task耗时比其它Task高出一个数量级而且同一Stage里大量Task已经Success了就剩几十个还在跑。这种图我这边一天能见好几回不用任何监控平台肉眼就能扫出来。判定倾斜先看Shuffle Read Size这一列。正常的任务之间这个值的分布应该是相对均匀的如果出现了某个Task的Shuffle Read Size是其它Task的5倍以上倾斜就已经成立了。这时去点开那个异常Task看它的日志里有没有spill相关的记录如果有问题基本进入了内存和磁盘的双重困境。代表成功后还有一类倾斜是从界面数字上看不出来的但会在运行时间上暴露比如Task Deserialization Time或Executor Computing Time异常而Shuffle Read Size不大——这多半是计算逻辑本身有热点键某一条key的维表关联或者循环处理本身耗费极高。这种问题靠改参数没用得改代码典型做法是把倾斜的key打散成随机前缀再和维表做两次join。页面下方的DAG Visualization也是一大信息来源但大多数人只会在作业失败时去看一眼平时根本不看。我建议你把DAG当成一个执行叙事线来看每个方框代表一个RDD转换或算子连线代表数据依赖关系。一旦出现Exchange节点就说明这里发生了Shuffle如果DAG里一个Stage内部出现了两次Exchange那大概率是执行计划没有优化干净——比如多表join时Spark没有把条件推下去生成了冗余的shuffle。这种时候去看看spark.sql.autoBroadcastJoinThreshold有没有生效小表如果超过默认的10MB阈值Spark就不会广播它转而走SortMergeJoin多一次shuffle传到UI上的体现就是Stage数变多、耗时变长。把这个阈值适当调大比如调到20MB很多中小维表的Join作业能明显提速。Stage页面还有两个不太起眼的数字Scheduler Delay和Task Deserialization Time。如果Job运行中Executors健康稳定这两个值也正常问题就不在资源申请和网络传输层面但如果Scheduler Delay非常高通常有两种可能一是动态资源分配spark.dynamicAllocation.enabled在反复调整Executor数量每次调整都要做存量Task的重新调度中间会产生较长的空窗二是你开了太多的spark.sql.shuffle.partitions导致单个Stage创建了上万个极小的Task调度器光是分发这些Task就耗掉了大把时间。4. SQL执行计划与参数联动不只看“对不对”还要看“为什么会这样”SQL标签页里最有价值的东西在Physical Plan那一栏。点进去你能看到Spark准备怎么执行你这套查询但默认展示的是一棵长的要命的树新手想着去读每个节点是浪费时间更简单的切入口是找关键词Exchange、Sort、Shuffle、Broadcast、Scan这几个词盯住就够。比如说你在SQL页看到最终的物理计划里有一个大扫描节点的输入量是数TB级别而这个扫描上面没有跟任何Filter或Projection下推那说明你的分区过滤条件没有生效。UI上显示是执行引擎老老实实把全表数据读出来再筛这就是典型的Partition Pruning失效代码里大概率是写了对分区字段做了函数运算比如to_date(col)再拿去查Spark在无法对函数结果做静态判断时只能退化成全表扫描。这个问题的解法不是调参数是改SQL先算出日期范围再用和直接过滤。紧接着看Exchange出现的次数和位置。正常的Reduce阶段在两个Stage之间只需要shuffle一次如果是同一张表在同一个Stage里出现了多个Exchange那多半是逻辑里的Join顺序没有选好。Spark默认用SortMergeJoin来处理两张大表join但如果一张大表经过过滤后实际参与Join的数据量已经缩到很小就不如用广播。这里有个关键参数spark.sql.adaptive.enabled——我会建议在海量数据作业里直接打开。它能在运行时根据统计信息重新优化执行计划如果前面那一轮过滤已经把一张表缩到很小自适应优化器会自动把SortMergeJoin替换成BroadcastHashJoin在UI里看到的结果就是Exchange节点变少了。不用手动改多少代码效果立竿见影。关于自适应执行还有一个专门对应的UI变化如果开了AQEAdaptive Query Execution在SQL页的计划里你会看到一些动态调整的标注例如预估的分区数不再等于spark.sql.shuffle.partitions的设置值而可能被动态缩小。很多人会奇怪我明明设置了200个分区怎么页面上只有几十个其实这是AQE在根据末端阶段的实际数据量自动合并了稀疏分区默认由spark.sql.adaptive.coalescePartitions.enabled控制。这个功能我在生产环境一直是打开的它能省掉大量小文件写出的问题尤其是下游要接Hive分区表时动不动几百个小文件能把文件系统MetaStore压垮。另外SQL页面还有一个Metrics列里面的scan time、output rows很重要。跑一遍相同SQL如果前后两次scan time相差巨大别急着怀疑机器变慢了先检查是不是跑到了同一个资源池里、以及是否因为前一次作业的缓存未清理导致数据落在了内存。UI里看到的scan time反映的是真实I/O开销把它和parquet列裁剪打开与否关联起来能让你的排查维度更立体。5. 参数调整如何闭环验证先改一处UI上追踪三十分钟讲了不少UI观察和参数关联再说说实际调优中最容易翻车的地方改完参数没有在UI上闭环验证急急忙忙就上线。我自己定的一个工作习惯是每次只改一个参数不要一次把spark.executor.memory、spark.sql.shuffle.partitions、spark.executor.cores三样全动了。原因很简单如果你同时改了三个作业运行变快了你根本分不清是哪个改动起了作用如果你改了三个且作业变慢了你同样拆解不开。一次只动一个拿去跑在UI上明确观察到对应指标数值发生变化再决定是继续调整还是回滚。一个常见的调整链路是先在Executors页发现Shuffle Spill (Disk)过高回来把spark.sql.shuffle.partitions从默认值200调整为400再次运行在Stage页面看到单个Reduce Task的Shuffle Read Size从之前动不动几百MB下降到300MB以内。如果Job变快继续观察GC Time和Spill是否同步下降这一刻才叫闭环。如果调整后Job反而慢了多半是分区数过大导致调度开销压过了收益UI上看到的现象就成了Scheduler Delay抬升这时就需要往回再微调一档。还有一个我踩过不少次的坑长时间占用Storage Memory不释放。起因通常是用cache()或persist()缓存了较大的RDD结果但后续逻辑并没有复用到它造成Storage页里显示的缓存数据一直占用着内存挤占了执行内存的空间。这种问题你在UI上看能发现Redis里叫淘汰Spark里叫溢写。处理办法其实很简单——用unpersist()主动释放或者在存储级别上选择MEMORY_AND_DISK_SER让缓存数据可以序列化落盘而不是必须驻留内存。只要你在Storage页看到缓存块的存在时间远大于作业的实际有效使用周期就说明资源哪儿漏了。关于动态资源分配再多说一句spark.dynamicAllocation.enabled开启后配合外部Shuffle服务spark.shuffle.service.enabled同时启用才能让executor在空闲时被安全释放。很多人在YARN模式下会忽略后者的配置结果动态缩容的Executor把Shuffle中间数据带走了后续任务读不到数据UI上表现出来的是大量FetchFailed异常和Stage重试。这个报错的复现过程在Stages页里会反复出现排查时看到FetchFailed先别急着加内存检查一下是不是Shuffle服务本身没起。6. 写在最后UI不是给领导看的仪表盘是你自己的排错罗盘我见过不少团队的Spark监控面板搭得很漂亮各种Grafana指标大屏但作业一出问题最后还得靠Spark UI一页一页翻。不是指标系统没用而是UI提供的是任务级别的执行真相——哪个Stage卡住、哪类Task重试、哪个Executor被驱逐这些细节层面做精细调优时只有原生的UI能给你这么完整的信息链。我的习惯是把常用的参数调整组合做成自己的一个小手册比方说现象优先检查页面函数首选参数Executor频繁GCExecutors页GC Time列spark.executor.memory、spark.executor.memoryOverheadFactor数据倾斜Stage详情页Shuffle Read Size分布spark.sql.adaptive.skewJoin.enabledShuffle溢出磁盘Task日志里spill记录spark.sql.shuffle.partitions调度延迟高Stage页Scheduler Delay列spark.sql.adaptive.coalescePartitions.enabled在启动一套调优之前先把这套表格看一遍结合UI体现出的当前作业特征去选对应的参数而不是照着网上流传的“最佳实践配置”直接抄。每个集群的网络带宽、磁盘IO能力、YARN队列资源各不相同能解决我这边数据倾斜的参数在你那边不一定灵关键是掌握从UI现象反推参数问题的思考方式。最后分享一个小技巧重跑同一作业时别反复刷新Jobs列表看结果而是盯住Stage页的进度条颜色变化。Stage状态从Pending到Scheduled再到Running颜色由灰变黄再变绿如果看到某个Stage长时间停在橙色或者局部Task反复变红那比等Job整体失败信息更早暴露问题。越早发现越早处理调优的时间成本能压缩到最小。
延伸阅读

更多相关文章

2026/9/29 16:30:14

广工2015计算机网络实验报告:Wireshark抓包与Socket编程实操存档

简介:这份资源是广东工业大学2015年计算机网络课程的实验报告PDF,面向计算机相关专业学生及网络初学者,可用于参考实验流程、撰写课程报告或复习交换机与路由配置。报告围绕GNS3网络仿真平台展开,涵盖拓扑搭建、设备基础操作、交换…

2026/9/29 16:30:14

TensorFlow.js 浏览器端深度学习:架构内幕与算力调度实战

1. 浏览器端深度学习的真实战场:为什么要在浏览器里跑模型把深度学习模型塞进浏览器,这件事在五年前听起来还像是极客的玩具,但今天它已经成了很多产品绕不开的工程选择。TensorFlow.js 就是这条路上最成熟的一条通道。它让你用 JavaScript 直…

2026/9/29 16:25:14

starnet 深度拆解:local-first + MCP 的本地 AI agent 调度框架

1. 从“starnet”这个名字说起:它到底想解决什么问题第一次看到“starnet”这个项目名,我下意识以为又是一个网络监控或者分布式组网的工具。直到把它的关键词摊开——AI agents、desktop harness、local-first、MCP——才反应过来,这其实是一…

2026/9/29 18:45:54

VM虚拟机欧姆龙PLC通讯实战:桥接模式与FINS协议配置指南

1. 为什么要在VM虚拟机上做欧姆龙PLC通讯1.1 搞清VM在通讯中的真实角色先说个我经常遇到的场景:现场用了博途或者CX-Programmer这些老牌PLC软件,但电脑系统太新,软件装不上;或者公司信息安全规定必须用虚拟机隔离环境;…

2026/9/29 18:45:54

ORB-SLAM3 TUM-VI配置全解析:鱼眼相机与IMU参数调优实战

1. 为什么TUM-VI数据集的配置值得单独拿出来讲ORB-SLAM3 是当前视觉惯性 SLAM 领域里少数同时支持单目、双目、RGB-D 以及视觉惯性融合的完整开源系统。很多人第一次跑通它,用的是官方仓库里自带的 EuRoC 示例,改个路径就能出轨迹。但一旦换成 TUM-VI 数…

2026/9/29 18:45:54

ROS2与Gazebo机器人仿真环境搭建避坑指南:从版本选型到实战调试

1. 为什么ROS2新手总在Gazebo仿真环境上栽跟头刚接触ROS2的人,十个里有八个会在Gazebo仿真环境搭建这一步卡住。不是Gazebo启动后黑屏,就是模型加载不出来,再不然就是ROS2节点和Gazebo之间死活通信不上。我自己第一次搭的时候,光是…

2026/9/29 18:45:54

AgentScope:面向生产环境的工业级Agent操作系统

1. 这不是又一个“AI Agent框架”:AgentScope到底在解决什么真问题?最近在几个技术群里看到有人甩出一句“推荐一个牛逼的AgentScope系统”,底下立刻跟了一串问号和“1”。我点开搜了下,发现满屏都是agentscope、agentscope 2.0、…

2026/9/29 18:45:54

大模型低精度计算:FP16、FP8、FP4 有什么差别?

FP16、FP8、FP4,到底差在哪? FP16、FP8、FP4并不是一条位宽递减线,跨过16位后通常要换成scale、量化和低bit内核。 **核心判断:**从FP16/BF16的范围问题,到FP8/INT8的两把8位尺子,再到FP4的分组scale。 …

2026/9/29 18:40:54

XXL-JOB 容器化部署实践:一套稳定可用的 K8s YAML 方案解析

简介:一份面向Kubernetes运维与开发人员的XXL-JOB容器化部署配置,基于实际集群环境验证通过,适用于需要快速上线xxl-job调度中心或调整既有部署方案的场景。资源包整体极为精简,仅含1个yaml文件,压缩包大小782B&#x…

2026/9/29 11:07:23

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/9/28 6:05:15

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/29 7:00:49

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/29 0:04:04

AI Evals实战指南:从零搭建LLM应用评估体系与CI/CD集成

1. 为什么AI Evals值得你花时间搞明白做LLM应用的人,迟早会撞上同一堵墙:模型输出飘忽不定,今天答得好好的,明天换个问法就胡说八道。你改了一版提示词,感觉好像好了点,但到底好了多少?说不清。…

2026/9/29 0:04:04

Java采购管理系统实战:从数据库设计到事务一致性

简介:这是一套面向Java Web初学者与课程设计者的采购管理系统完整源码,采用JSP技术搭建,配合MySQL数据库,用于解决企业采购信息的管理问题,适合作为毕业设计、课程大作业或进销存类项目的参考模板。系统实现了用户登录…

2026/9/29 3:53:39

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/29 9:46:12

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/29 6:36:14

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑