ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

深入剖析Spark UI界面:参数与界面详解

深入剖析Spark UI界面:参数与界面详解 一、概述Spark UI是Apache Spark内置的Web监控界面为开发者和运维人员提供对Spark应用程序执行过程的实时、可视化洞察。它以直观的方式展示作业Jobs、阶段Stages、任务Tasks、SQL执行计划、Executor资源使用、存储状态及运行时环境等关键信息。通过Spark UI用户可以快速定位性能瓶颈如数据倾斜、Shuffle 开销、调度延迟、分析执行计划、监控资源利用率并进行有效的调优与故障排查。无论是开发调试还是生产运维Spark UI都是理解和优化Spark应用不可或缺的核心工具。二、Spark UI 一级入口打开Spark UI就会看到当前的一个Jobs页面这个页面会记录当前作业中数据的移动读取等相关动作除此之外一级入口还会包括作业运行时的其他属性与指标主要包括Stages、Storage、Environment、Executors、SQL 。一级入口界面如下所示首先我们由简入繁从衡量任务的整体指标依次介绍各个入口的的功能与作用首先我们先看Executors先对作业整体的一个计算负载进行了解。ExecutorsExecutors Tab主要包括两部分Summary和Executors两部分其中Summary是所有的Executors度量指标的加和而Executors则是描述每一个Executor的详细信息粒度会更细方便对每个Executor的情况进行了解下面我们对Spark UI对Executors提供的Metrics进行介绍方便我们对每个Executor节点的运行情况有更好的了解Spark UI中的Executors界面是监控和诊断Spark应用运行状态的核心窗口之一它从执行器Executor粒度展示了整个集群的资源使用、任务负载和数据分布情况以及它们对CPU、内存与磁盘等硬件资源的消耗。基于这些信息我们可以看到不同的Executor的状态是否有个别的Executor存在负载不均衡的情况从而快速的定位问题例如数据倾斜等。Environment这里说一下Environment显而易见这里主要展示我们的任务的一些配置项它主要包括五大环境信息通过查看Environment的信息我们可以快速获取当前任务的配置信息这里主要查看Spark Properties信息来去判断当前任务的配置项是否符合我们的预期从而作出适当的调整优化任务的性能。StorageSpark UI中的Storage界面 是用于监控和管理 缓存数据Persisted/Cached Data的核心窗口。它直观展示了哪些RDD或DataFrame被缓存、缓存在哪里、占用了多少资源是优化内存使用和避免OOMOut of Memory的关键工具。Cached Partitions与Fraction Cached分别记录着数据集成功缓存的分区数量以及这些缓存的分区占所有分区的比例。而当Fraction Cached没有达到100%时说明该数据集未能完全缓存在内存参照spark内存管理可知此时会出现数据换入换出的情况显性的说明此时需要参与的计算量大执行内存会占用缓存内存Size in Memory与Size in Disk则更加直观地展示了数据集缓存在内存与硬盘中的分布。SQLSpark UI中的SQL页面SQL Tab是Spark SQL / DataFrame作业的核心监控与优化入口。它专为结构化查询设计将逻辑执行计划、物理执行过程、性能瓶颈和数据流动以可视化方式呈现是诊断慢查询、验证优化策略、理解AQE行为的“驾驶舱”。StagesSpark UI的Stages界面 是性能调优和故障诊断的核心入口。它从Stage阶段粒度展示了Spark作业的执行细节帮助你精准定位慢任务、数据倾斜、资源瓶颈等问题。JobsSpark UI的Jobs界面 是整个Spark应用监控体系的顶层入口它以Job作业为单位提供全局视角的执行概览帮助你快速判断应用整体健康状况、识别失败作业、定位性能瓶颈起点。至此我们已对Spark UI导航栏中的各个页面进行了不同程度的解析。整体来看这些页面可分为两类“详情型”页面包括Executors、Environment和 Storage它们直接展示集群的系统级状态——如计算资源负载分布、运行时环境配置、缓存数据详情等。开发者无需额外跳转即可快速获取关键的底层信息。“概览 下钻型”页面包括SQL、Jobs 和 Stages:它们首先以列表形式提供作业或查询的高层汇总视图若需深入分析执行计划、任务分布、性能瓶颈等细节则需点击进入对应的二级详情页进行下钻探查。这种分层设计既支持快速概览又保留了深度诊断的能力为开发者提供了从宏观到微观的完整观测路径。三、Spark UI 二级入口二级入口指的是需要通过一次超链接点击才能进入的详情页面。对于SQL、Jobs和Stages这三个主入口而言其对应的二级页面通常已包含极为丰富的诊断信息——涵盖查询执行计划、作业生命周期、任务级性能指标等基本构成了Spark应用的“健康体检报告”核心内容。接下来我们将按照SQL → Jobs → Stages的逻辑顺序依次深入这三个二级详情页系统性地剖析全局DAG执行结构来自SQL页面作业的完整执行流程与依赖关系来自Jobs页面以及各计算阶段Stage的资源使用与运行细节来自Stages页面。通过这一层层递进的分析路径我们将获得对Spark应用执行行为更全面、更深入的洞察。SQL详情页通过点击图中的with…可以进入到该作业的详细执行界面在数据分析场景中大部分的操作包括过滤、分组、聚合、关联、排序。所对应的执行计划图中Exchange代表的是Shuffle操作Sort代表的是排序Aggregate代表的是数据聚合。这三类操作是硬件资源如 CPU、内存、磁盘和网络的主要消耗者。与此同时Spark UI也为它们分别提供了丰富的细粒度指标Metrics用以精确刻画各类资源的使用情况。接下来我们将聚焦于这三类操作深入解析其对应的度量指标以更好地理解资源消耗模式并指导性能调优。Exchange可以看到针对每一个Exchange操作Spark UI都提供了全面而细致的指标Metrics完整覆盖了Shuffle的整个生命周期——从Shuffle Write到Shuffle Read从数据规模到处理耗时关键维度一应俱全。为了便于理解和参考我将这些Metrics的含义和作用整理成表格形式Sort可以看到“Peak memory total”和“Spill size total”这两个数值足以指导我们更有针对性地去设置spark.executor.memory、spark.memory.fraction、spark.memory.storageFraction从而使得Execution Memory区域得到充分的保障。Aggregate对于Aggregate操作Spark UI也记录着磁盘溢出与峰值消耗即Spill size和Peak memory total。这两个数值也为内存的调整提供了依据。Stages详情页在所有二级入口中Stage详情页的信息量可以说是最大的。点进Stage详情页可以看到它主要包含3大类信息分别是Stage DAG、Event Timeline与Task Metrics。其中Task Metrics又分为“Summary”与“Entry details”两部分提供不同。Stage DAG我们首先来看最简单的Stage DAG如下图所示之所以说Stage的DAG相对简单是因为我们已在SQL页面的二级详情中对完整的执行DAG进行了深入解析。而Stage级别的DAG本质上只是该作业Job整体DAG的一个局部片段——它仅对应其中某一个计算阶段。因此一旦你理解了SQL页面中面向整个Job的完整DAG结构Stage 层面的DAG自然也就一目了然、无需重复深究了。Event TimelineEvent Timeline记录着分布式任务调度与执行的过程中不同计算环节主要的时间花销。图中的每一个条带都代表着一个分布式任务条带由不同的颜色构成。其中不同颜色的矩形代表不同环节的计算时间。在理想情况下Spark任务的时间条带Timeline应以绿色部分Executor Computing Time为主这表明大部分时间都用于执行实际的计算逻辑而系统开销如调度、I/O、Shuffle 等被有效控制在较低水平。然而实际情况往往更为复杂。你可能会观察到深蓝色部分Scheduler Delay占比过高说明任务在等待资源调度上耗费了大量时间黄色Shuffle Write Time和橙色Shuffle Read Time显著膨胀表明 Shuffle 阶段成为性能瓶颈。这些现象说明性能瓶颈并不在计算本身而是出在调度或数据交换环节。如何针对性优化针对调度延迟高Scheduler Delay 大可参考以下经验公式进行资源配置调整DP∼MCPD∼CM其中DD 数据集大小PP 并行度Partition 数量MM 每个Executor 的内存CC 每个Executor的CPU核数公式含义每个任务处理的数据量 D/PD/P 应与单个任务可使用的计算资源 M/CM/C即单位CPU核对应的内存处于同一数量级。若D/PD/P远大于M/CM/C说明任务过重或资源不足容易导致调度排队反之则可能资源浪费。通过合理调整并行度PP 、Executor 内存MM和CPU核数CC可有效降低调度开销。针对 Shuffle 负载重Shuffle Read/Write 时间长当黄色和橙色区域占比过大时说明任务存在大量跨节点数据交换。此时应考虑是否可以使用Broadcast Join若其中一张表较小通常100MB可将其广播到各节点从而完全避免Shuffle。其他优化手段包括合理设置spark.sql.adaptive.enabled启用AQE自动合并小分区调整spark.sql.shuffle.partitions避免过多小文件使用repartition或coalesce优化数据分布。Task MetricsTask Metrics任务指标是Spark在每个Task执行完成后收集的一组细粒度性能与资源使用数据全面刻画了该Task的执行行为。这些指标构成了Spark UI尤其是 Stages 页面中各类可视化分析如时间条带、Shuffle 统计、内存使用等的底层数据基础也是进行性能调优、故障排查和资源规划的核心依据。在分析时通常先从粗粒度的“Summary Metrics”入手——它是对所有Tasks执行指标的统计汇总能够快速反映整个Stage的整体表现随后再深入到细粒度的“Tasks”列表逐个排查异常或低效的Task实现精准定位与优化。Summary Metrics点击Select All使当前所有度量值都生效首先把Metrics整理到表格中特别值得关注的是Spill (Memory) 和Spill (Disk) 这两个指标。在Spark执行过程中当用于缓存中间数据的内存结构如PartitionedPairBuffer或AppendOnlyMap达到容量上限时系统会将部分数据“溢出”spill到磁盘以释放内存空间。Spill (Memory) 表示这些被溢出的数据在内存中的原始大小即未落盘前的字节数Spill (Disk) 则表示这些数据实际写入磁盘后的大小通常经过序列化和压缩。通过计算两者的比值Explosion Ratio≈Spill (Memory)Spill (Disk)Explosion Ratio≈Spill (Disk)Spill (Memory)我们可以得到一个近似的 “数据膨胀系数”Explosion Ratio。该系数反映了单位磁盘存储所对应的实际内存占用。有了这个比率当我们知道某份中间数据在磁盘上占用了多少空间时就能反推出它在内存中大概会消耗多少资源。这为精准评估内存需求、预判OOM风险、合理配置Executor内存提供了重要依据。例如若Explosion Ratio 3.0意味着磁盘上1GB的spill数据在内存中实际占用了约3GB若该值远大于1说明数据在内存中高度“膨胀”需警惕内存压力若接近1则表明序列化/压缩效率高内存与磁盘占用接近。Tasks在介绍完粗粒度的Summary Metrics后我们进一步深入到更细粒度的Tasks列表。实际上Tasks表格中展示的许多指标如 Duration、Shuffle Read Size、GC Time 等与Summary Metrics中的内容高度一致其含义完全相同因此无需重复解释——你可以直接参照前文对Summary Metrics的说明来理解这些字段。两者的核心区别在于Summary Metrics提供的是对所有Tasks的聚合统计例如最小值、中位数、最大值等用于把握整体趋势Tasks列表 则逐行展示每个Task的具体指标值呈现个体行为。这种细粒度视图特别适用于定位异常任务例如执行时间显著偏长的Task;Shuffle 读取数据量异常高的Task;发生磁盘 Spill 或 GC 耗时过长的Task。通过对比单个Task与整体统计的偏差可以快速识别性能瓶颈或数据倾斜问题从而实现精准的故障排查与调优。新增的指标并不多其中最值得关注的是 Locality Level本地性级别。正如调度机制中所讨论的每个Task在提交时都会携带一个本地性偏好locality preference用于指示它希望在哪个层级上访问其输入数据——例如是否优先在数据所在的节点、机架或任意节点上执行。Spark调度器会尽可能依据这一偏好将 Task 分配到靠近其所需数据的 Executor上。这一机制的核心目标正是践行Spark的核心设计原则“数据不动代码动”。通过将轻量级的计算逻辑移动到数据所在的位置而非将大量数据跨网络传输到计算节点从而显著减少网络 I/O 开销提升任务执行效率。因此Locality Level不仅反映了任务调度的亲和性也是评估数据局部性优化效果的重要依据。四、实战环节这里我们选两个典型的例子进行分析调优案例一scan表慢和内存问题如上图所示我们选择运行时间最长的一个Stage进行具体分析调优点进去进入该Stage内部如下所示观察如上指标会发现两个问题点1.这里单个Task处理的数据量为25MB左右正常来说一个Task处理的数据量为128-256MB较为合理这是由于原始表的数据量大小文件太多导致分配的Task数据量过大。2.并且由第二个图可知失败重试的Task的调度等待时间过长这是由于Task数据量过多而实际并发只有1000导致部分Task调度时间太长导致。对于上述问题我们可以通过设置表的切片大小缓解问题set spark.sql.odps.split.size.du_shucang.dws_traffic_algo_search_keyword_stats_di512MB添加如上参数后观察效果我们第一次将切片大小控制到512MB来减小实际Task数可以看到相对于上次该Stage会快20min这里我们还可以继续增大表的切片来迭代看效果感兴趣的可以自己尝试。我们在从另外一个角度看待问题当我们试图减小分配给Stage的Task数量时那么Task的实际处理数据量就会增大这里我们可以通过减小spark.executor.cores的核数来隐形的增大Task的内存或者调大spark.executor.memory的内存来显性的增大Task的内存这里由于Task的量级太多我们选择增大spark.executor.memory来进行优化效果如下所示这里由于本身Task处理的数据量是很小的所以无法很显著的看到效果若是出现下图所示的情况调大内存效果会更显著些总结在Spark中当读表时由于数据量大而此时Task处理的数据量又过小时可以通过set spark.sql.odps. split.size.xxxxxMB来减小task数量而通过Spill和Spill Memory Disk来观察其是否需要增大内存或者实际并发量。案例二shuffle之后并行度不足该case打不开了之前记录的随便拿了一个还是老样子降序查看最大的。分析是在Shuffle阶段并行度提升不了。总结在Spark中Join、Group都会在Shuffle阶段产生并行度这个Shuffle是一个很大的池子可以利用万能参数进行增加并行度。读取Shuffle数据的目标大小 提高AQE shuffle默认分区数“spark.sql.adaptive.advisoryPartitionSizeInBytes”:“64MB”;“spark.sql.adaptive.coalescePartitions.initialPartitionNum”:“1000”.注意有些时候会发现增加了还是没变那是因为切分还是太大。1,2切分3调整限制。“spark.sql.adaptive.advisoryPartitionSizeInBytes”:“8KB”,“spark.sql.adaptive.coalescePartitions.minPartitionSize”:“8KB”“spark.sql.adaptive.coalescePartitions.initialPartitionNum”:“3000”.五、总结总的来说我们通过Spark UI界面去优化亦或者去定位错误都离不开内存与并行度这两个大的维度通过相应的Summary Metrics我们可以很好的定位到问题所在是内存过小还是并行度不够事实上内存与并行度并不是独立的而是相互影响相互制约的一种关系并行度决定了“有多少个Task同时运行”而内存决定了“每个 Task能分到多少资源”。当并行度一定的时候当我们试图通过调大内存来解决问题而问题并未得到解决的时候实际上当内存变大而实际并行度固定时每个Task所分配的内存就会增大所带来的额外开销就是做内存穿透的时间增加从而GC时间增大。当内存一定时我们去调大并行度或者增大核数时每个Task所分配的内存就会变小就会容易出现内存溢出的风险。对于一个任务那我们如何去合理的配置其并行度和内存这里我们可以看一个任务耗时最长的的几个Stage假设某个Stage的并行度为5000而此时所给的参数为executor.memory12g,executor.cores4,spark.dynamicAllocation.maxExecutors250此时集群最大并行度250*41000也就是说当前任务需要分5批执行此时集群中一个Task内存为3g按照经验论每Core对应48GB内存是合理的而处理的总并发度通常会是实际并发度的2~3倍为合理因此我们将参数设定为 executor.memory16g, executor.cores6来进行一个迭代优化。一个好的Spark作业Task均衡、无Spill、CPU打满、内存够用这是我们去做优化的一个理想状态
返回列表