Engineering Manager / Data · HM Technical Discussion

Apple Spark 两张大表 Join:计划、倾斜与预聚合取舍

针对双方都大的 Join,先核键与基数,再看 AQE、shuffle、倾斜和可复用物理布局。

题目重点:针对双方都大的 Join,先核键与基数,再看 AQE、shuffle、倾斜和可复用物理布局。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练版以两张均无法整体广播的大表按等值键 inner join 为例;若其中一边过滤后足够小,广播可能是另一方案。
  • 精确结果需保留重复键的多对多行数,不能为了性能无条件去重或仅保留任意一行。

解题路线

  1. 先确认 join 类型、键唯一性、NULL 语义、过滤条件和预期输出基数;执行 `explain` 并查看输入统计与实际 task 分布,判断瓶颈是扫描、shuffle 还是输出爆炸。
  2. 在 join 前过滤/列裁剪,能按业务等价规则预聚合的一边先缩小;但只有聚合结果能替代原明细时才做,不能改变多对多语义。
  3. 双方仍很大时通常需要按 join key 的 shuffle 计划;配置合适并行度与文件布局,使用可靠表统计。若两表已按兼容分区/桶布局存储,可评估减少重复 shuffle 的可行性。
  4. 热点键会使单分区超大:先分辨是正常高基数输出还是不均匀 shuffle;对可拆热点键做定向 salting、分离处理,或让 AQE skew join 优化。广播提示仅在过滤后小表足够小且节点内存可承受时使用。
  5. 测 shuffle bytes、最慢 task、输出行数和正确性对账;join hint 是建议,实际策略受 join 类型与优化器限制,不能只凭 hint 推断计划。

手动走一遍

A、B 都各有大量数据,键 X 在 A 有 10 万行、B 有 10 万行,则该键的 inner join 可能产生 100 亿行;这时单纯 salting 不能消除结果规模。若 B 实际先按条件过滤到很小,则可重新评估广播。数字只是数量级示例。

规模与取舍

等值 join 的网络 shuffle 通常与两侧参与记录规模相关,输出行数可能达同键频数乘积之和;最坏多对多输出可远大于输入。内存、磁盘与时延需按键分布和实际执行计划核算。

易错点与追问

容易失分的边界

  • 两张表都大却无依据强制 broadcast,一侧复制到所有 executor 触发 OOM。
  • 忘记重复键,误判结果规模。
  • 盲目 salting 但不复制匹配侧/不合并结果,漏行或重复。
  • 把 AQE 当万能修复,不看实际版本与开启状态。
  • 为提高速度随意去重,改变业务语义。

继续深挖

  • 一边过滤后 5MB,策略会怎样变?
  • 热点键代表真实多对多输出爆炸时怎样从产品需求降低结果?
  • 如何确认 AQE 实际改用了 skew join 优化?
  • left outer join 对广播方向和 NULL 有何约束?

技术参考

✓已复制微信号!