问题修复
编写或调优 Apache Spark 作业时:用…
在写 Spark 作业、调试性能问题或配置集群(DataFrame/SQL/RDD/结构化流)时,按此流程实现并优化分布式的 ETL 管道。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 49/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 85/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 60/100 ×0.15
适用场景
编写或调优 Apache Spark 作通用
解决思路
- 分析需求:先明确数据量、需要的转换、延迟要求与可用集群资源,再动手写代码。
- 设计管道:在 DataFrame 与 RDD 之间选型(结构化数据优先 DataFrame),规划分区策略,识别可广播的小表。
- 实现:编写带有优化转换、适当缓存与错误处理的 Spark 代码。
- 优化:分析 Spark UI,调优 shuffle partitions,消除数据倾斜,优化 join 与聚合。
- 验证:先看 Spark UI 是否有 shuffle spill;用 `df.rdd.getNumPartitions()` 核对分区数;若发现 spill 或倾斜就退回优化步骤;用生产规模数据测试、监控资源使用并验证性能目标。
- 按上下文加载对应参考文档:Spark SQL 与 DataFrame 看 `references/spark-sql-dataframes.md`;RDD 操作看 `references/rdd-operations.md`;分区与缓存看 `references/partitioning-caching.md`;性能调优看 `references/performance-tuning.md`;流处理看 `references/streaming-patterns.md`。
- 创建 SparkSession 时显式配置,例如 `.config("spark.sql.shuffle.partitions", "400")` 与 `.config("spark.sql.adaptive.enabled", "true")`。
- 生产环境读取数据时用 `spark.read.schema(schema).parquet(...)` 指定显式 schema,不依赖推断。
- 写出结果前先用 `print(f"Partition count: {result.rdd.getNumPartitions()}")` 核对分区数,再执行 write。
- 小维表(< 200MB)参与 join 时用 `broadcast(dim_df)` 显式提示广播。
- 处理数据倾斜用加盐:对倾斜侧用 `(F.rand() * SALT_BUCKETS).cast("int")` 加 salt 并 `F.concat` 出 `salted_key`;另一侧用 `F.explode(F.array([...]))` 复制 SALT_BUCKETS 份并同样加盐;join 后 `.drop("salt", "salted_key")`。
- 缓存只在 DataFrame 会被多次复用时使用:`.cache()` 后立刻 `.count()` 物化并在 Spark UI 检查 spill,用完 `.unpersist()` 释放。
- 结构化数据处理一律使用 DataFrame API,而不是 RDD。
- 分区数按每个 executor core 200–1000 个分区来设置。
- 持续监控 Spark UI 的 shuffle、spill 与 GC 指标。
- 必须用生产规模的数据量做测试。
- 不要对大数据集使用 `collect()`,会造成 OOM。
- 不要在没有测量收益的情况下缓存每一个 DataFrame。
- 不要忽略 shuffle partition 调优(默认 200 往往不合适)。
- 有内置函数可用时不要写 UDF(慢 10–100 倍)。
- 处理大量小文件前先 coalesce,避免小文件问题。
- 理解惰性求值,不要在没搞清楚 lazy evaluation 的情况下跑转换。
- 不要忽略 Spark UI 里的数据倾斜告警。
- 交付时给出:完整 Spark 代码(PySpark 或 Scala,带类型/type hints)、配置建议(executors、内存、shuffle partitions)、分区策略说明、性能分析(预期 shuffle 大小、内存占用)、监控建议(要盯的关键 Spark UI 指标)。
适用边界 · 注意事项
- 数据量小到单机 pandas 或 SQL 就能轻松处理时,没必要引入 Spark 的集群开销。
- 需要毫秒级低延迟响应或 OLTP 式单行事务更新的场景,Spark 不适合。