高性能 Spark UDF 开发手册

一、 架构设计篇:做减法

在写代码之前,先问自己:这个逻辑必须在 UDF 里做吗?

  • 过滤先行 :在调用 UDF 之前,先用 SQL 过滤掉 NULL、空字符串或明显异常的超长数据。
  • 并行度治理 :如果数据总量不大但 Task 极多(如你的 9 万个 Task),在 UDF 执行前调用 .coalesce(适当分区数)。减少 Task 切换和广播变量重复初始化的开销。
  • 拆分"大数组" :如果单行数据包含巨大数组(如 applicants 过长),考虑先在 SQL 层 explode 炸开,处理完后再聚合,避免单行数据卡死单个 Executor。

二、 初始化篇:利用 initBroadCast

initBroadCast 是"一次性"的准备工作,要在这里完成所有昂贵的操作。

  • 广播变量 (Broadcast):用于加载几百 MB 以内的只读映射表。它能避免几万个 Task 重复下载数据。

  • 工具类单例化 :类似 AddressParseUtils 这种工具类,在 initBroadCast 中初始化一次,作为类成员变量供 call 复用。

  • 预编译正则禁止 在循环内使用 str.replaceAll("regex", "")。必须在类成员位置预编译:

    private static final Pattern MY_PATTERN = Pattern.compile("...");


三、 执行篇:内存与 CPU 的"极致压榨"

call() 方法每秒可能被调用数万次,这里的代码必须"滴水不漏"。

  • 对象复用 (Zero-Allocation)
    • 不要 在循环内 new Entity()new ArrayList()new Map()
    • 做法 :在类成员定义一个 reuseEntity,每次循环调用 set 方法重置它的值。
  • 告别语法糖
    • 禁用 Java 8 Stream API (.stream().filter().findFirst())。
    • 做法 :回归最原始的 for 循环。流操作产生的中间对象是海量 GC 的罪魁祸首。
  • 字符串调优
    • 字符串是不可变的,连续的 replace()toUpperCase() 会产生大量垃圾对象。
    • 大量拼接时使用 StringBuilder 且手动 setLength(0) 复用。

四、 性能诊断篇:通过 Spark UI 看穿本质

当任务变慢时,盯着这几个指标:

  • GC Time:如果 GC 时间超过 Task Duration 的 10%,说明你的 UDF 产生了太多临时对象,或者广播变量太大。
  • Duration (Max vs Median):如果 Max 远大于 Median,说明存在数据倾斜。检查是否某些行的数据量(如数组长度)异常大。
  • Input Size / Records :查看每个 Task 处理的数据分布,如果每个 Task 只有几 KB,说明分区太多,需要 coalesce

五、 避坑口诀(开发 Checklist)

一禁: 禁用循环内 new 对象。

二禁: 禁用循环内 Stream 流。

三禁: 禁用循环内正则编译。

一复: 复用成员变量与工具类。

二复: 复用静态常量与映射 Map。

相关推荐
二哈赛车手1 小时前
新人笔记---ApiFox的一些常见使用出错
java·笔记·spring
栗子~~2 小时前
JAVA - 二层缓存设计(本地缓冲+redis缓冲+广播所有本地缓冲失效) demo
java·redis·缓存
阿星AI工作室2 小时前
刘润年中大课笔记:一句话说清AI落地之战的本质
大数据·人工智能·创业创新·商业
YDS8292 小时前
DeepSeek RAG&MCP + Agent智能体项目 —— RAG知识库的搭建和接口实现
java·ai·springboot·agent·rag·deepseek
未若君雅裁3 小时前
MyBatis 一级缓存、二级缓存与清理机制
java·缓存·mybatis
AI人工智能+电脑小能手4 小时前
【大白话说Java面试题 第65题】【JVM篇】第25题:谈谈对 OOM 的认识
java·开发语言·jvm
阿维的博客日记4 小时前
Nacos 为什么能让配置动态生效?(涉及 @RefreshScope 注解)
java·spring
雨辰AI4 小时前
SpringBoot3 + 人大金仓读写分离 + 分库分表 + 集群高可用 全栈实战
java·数据库·mysql·政务
辰海Coding5 小时前
MiniSpring框架学习-完成的 IoC 容器
java·spring boot·学习·架构
小小编程路6 小时前
C++ 多线程与并发
java·jvm·c++