数据任务使用什么技术底座,耗时与性能如何优化?

考查重点:计算阶段与数据搬运瓶颈。分别讲存储/表格式、计算引擎和调度,量排队、扫描、Join、Shuffle,针对最大段优化后同负载复测

本题目录

参考答案

核心回答

数据任务的技术底座要按存储、表与元数据、计算、资源管理、任务调度说明各自分工,再把运行时长落到一条具体链路上。性能优化先看任务从提交到结果可用的时间花在哪:是等上游、排队等资源,还是扫描、Join、聚合或写出慢;随后结合执行计划和任务指标定位瓶颈,再做有针对性的修改。

可以用离线订单指标加工举例:原始数据存放在 HDFS 或对象存储,Hive Metastore 管理表与分区信息,Spark SQL 完成清洗、维度关联和聚合,YARN 或 Kubernetes 分配计算资源,调度平台处理依赖、定时运行和失败重跑。这是一种参考组合,回答项目时按实际架构替换;如果使用 Iceberg,它承担表格式和元数据管理职责,Spark 仍负责计算。

优化时,扫描过多就检查分区裁剪与列裁剪,Join 或聚合长尾就检查数据分布和 Shuffle,排队慢就处理资源竞争与调度。修改后,在相同数据口径和可比资源条件下,比较总耗时、长尾、资源消耗与结果一致性,说明优化了哪一段、付出了什么代价。

运行时长要讲清口径

“任务跑多久”至少有两种常见口径:从作业提交到执行完成,或从业务计划产出时间到数据通过质量检查、可供下游使用。后者还可能受到上游延迟、调度依赖和发布过程影响。

介绍一条任务时,交代处理的业务日期范围、输入行数与字节量、全量还是增量、调度频率,以及常态和高峰时段的完成情况。把总耗时进一步拆成等待资源、执行和提交发布等阶段,便于解释瓶颈。DAG 中多个分支可能并行,端到端耗时取决于关键路径,不能简单把所有任务耗时相加。

资源也要一起说明:相同 SQL 在不同 executor 数量、单个 executor 内存、存储吞吐和并发负载下,运行时间可能不同。比较优化结果时,这些条件决定了“更快”来自代码改进、资源增加,还是刚好避开竞争。

从执行证据定位瓶颈

以 Spark 批处理为例,先从调度实例定位到 application、SQL、stage 和 task,结合执行计划找出耗时集中在哪个算子,再看对应指标:

  • 开始执行之前就等很久。 检查上游完成时间、资源队列、executor 申请情况和并发任务。此时只改 Join 算法,可能几乎不影响交付时间。
  • 扫描数据很多。 对照预期业务日期与实际读入分区、文件数和字节量,查看分区条件是否有效、是否读取了不需要的列,以及重复扫描是否有必要。
  • 少数 task 明显落后。 比较它们的输入量、Shuffle 读写量、持续时间和所在 executor。大部分 task 已完成只是长尾线索,还要排除节点慢、GC、网络等待或失败重试,才能判断是否数据倾斜。
  • 多数 task 都很重。 看单分区数据量、spill、GC 和可用并行度,区分分区过大、内存压力、低效计算和整体资源不足。
  • 执行很碎、文件特别多。 检查文件枚举、打开文件、任务调度及写出提交的开销。大量很短的 task 不一定代表整体效率高。

Spark UI 的 SQL、Stages、Executors 页面可以把执行计划与扫描、Shuffle、spill、GC、失败记录联系起来。作业结束后要回看这些信息,需要事先保留相应事件日志并通过 History Server 等方式查看。

按原因选择优化动作

先减少无效数据处理。 只读所需业务分区和列,尽早应用不改变语义的过滤;避免相同中间结果反复扫描。周期任务可以考虑增量计算,但需要定义迟到数据、更新删除和历史回补的处理方式,不能把当天增量直接当成完整业务结果。

再调整 Join 与聚合。 大事实表关联较小维表时,先过滤维表并保留必要列,再评估广播 Join。广播会把构建侧数据分发给 executor,可能减少大表 Shuffle,但要考虑过滤后的实际大小、内存占用、并发和 Join 类型;表的行数少不等于内存一定够,Hint 也不保证最终采用该策略。

如果热点键让单个分区承载大量数据,可以考虑单独处理热点、可合并聚合的局部聚合,或在语义允许时加盐拆分。加盐 Join 要处理另一侧复制与最终结果还原;COUNT DISTINCT 等计算也不能把各分片计数直接相加。应先说明为何结果仍然等价,再讨论并行度收益。

让分区和文件规模匹配任务。 分区过大可能导致 spill 和长尾,过小则增加调度与小文件开销。Spark 的 AQE 会利用运行时统计调整部分执行策略,包括合并小 Shuffle 分区、转换部分 Join 和处理部分倾斜 Join;它仍受版本、配置与算子支持范围约束。输入分区、Shuffle 分区和表的业务分区不是同一概念,不能用一个分区数解决所有问题。

小文件治理可以从上游写出方式、输出并行度和后续合并入手。强行把所有数据合成一个文件,会把写出变成瓶颈。缓存适合确实会重复使用、且收益能覆盖物化与存储成本的中间结果;单次使用的数据盲目缓存,反而可能增加压力。

最后看资源与链路治理。 若主要时间花在资源竞争,调整并发、错峰、优先级或资源隔离比单条 SQL 调参更直接。扩容则要确认计算或吞吐确实能随资源增加而改善。长期还可以删除无用任务、复用公共加工层、治理重复计算和失败重试,减少整条链路的资源消耗。

一个可以展开的项目回答示例

以下以“订单事实表关联维表后生成日报”为参考场景:

这条链路用 Spark SQL 计算,数据保存在分区表中,调度平台负责上游依赖和定时运行。优化时先从日报产出延迟追到对应 SQL 和 stage,区分等待资源与实际执行耗时。如果执行计划显示读取了无关日期,先修正过滤和分区访问;如果瓶颈集中在维度关联,再核对维表过滤后的大小、Join 基数及 task 分布,判断是否适合广播或需要处理热点键。每次只改有依据的部分,对同一业务数据比较执行计划、扫描与 Shuffle 指标,并核对订单数、金额汇总和关联缺失情况。最后说明日报是否更早可用,以及资源消耗和失败重跑有没有变化。

实际项目中,可在这个结构里补充任务记录中的耗时、数据规模、资源配置和自己的具体改动。优化结果既包括时间变化,也包括交付是否稳定、成本是否可接受;只给某个最快运行时间,往往解释不了高峰期表现。

常见追问

只有一个 task 很慢,就能断定数据倾斜吗?

先看数据量是否明显集中于该 task,再结合热点键分布和 Shuffle 情况验证。如果它的数据量正常,而 GC、远程读取等待或重试异常,应沿对应原因排查。

加 executor 为什么可能没有明显提升?

可能瓶颈在上游依赖、资源队列、单个热点分区、存储带宽或串行提交,也可能分区数量不足以用满资源。扩容能否有效,取决于当前瓶颈是否可并行、是否有足够数据分片。

怎样确认优化没算错?

先对齐输入快照、业务时间范围和去重口径,再比较行数、主键重复、关键聚合、空值和未关联比例;对关键业务样本逐条核对。还要覆盖迟到、重跑和回补,避免普通日期跑得快,特殊日期产生重复或漏数。

参考资料

相关面经

4 篇

OPPO

数据开发工程师
秋招一面
查看原面经 →
技术底座是什么,任务运行时长,性能问题与优化手段?

滴滴

数据开发工程师
秋招一面
查看原面经 →
关于链路调优,讲一个具体案例。

沐瞳科技

数据仓库开发工程师(AI)
校招秋招一面
查看原面经 →
简历提到链路性能优化,请从目标、具体动作、最终结果、技术深度来讲。
除了数据倾斜,还有哪些优化或治理工作?

阶跃星辰

大模型基础设施工程师(数据管道)
实习秋招一面、二面
查看原面经 →
性能调优有什么
怎么优化的

相关题目

4 题