SparkSQL 之 DataFrame 与 DataSet 及实操演练

摘要:从 RDD 到 DataFrame 再到 DataSet,Spark 的 API 经历了三次重大进化。DataFrame = DataSetRow(有 Schema 但无类型),DataSetT = RDD 的类型安全 + DataFrame 的 Catalyst 优化。本文从三层 API 架构全景、RDD/DataFrame/DataSet 创建与互转、Catalyst 优化器四阶段、Encoder 序列化机制、生产环境最佳实践五个维度,配合 1 张原创深色架构图 + 完整可运行实操代码,助你彻底掌握 SparkSQL 的 API 体系。

关键词:SparkSQL, DataFrame, DataSet, RDD, Catalyst, Encoder, SparkSession, Tungsten


一、开篇:SparkSession --- 万物入口

scala 复制代码
import org.apache.spark.sql.SparkSession

val spark = SparkSession.builder()
  .appName("SparkSQL Demo")
  .master("local[*]")
  .config("spark.sql.shuffle.partitions", "4")
  .getOrCreate()

import spark.implicits._  // 启用 RDD → DF 隐式转换 + Encoder

二、三层 API 架构全景图

核心关系

scala 复制代码
// DataFrame 本质
type DataFrame = DataSet[Row]  // DataFrame 就是无类型的 DataSet

// 互转关系
val rdd: RDD[Person] = ...
val df: DataFrame = rdd.toDF()          // RDD → DataFrame
val rdd2: RDD[Row] = df.rdd             // DataFrame → RDD
val ds: DataSet[Person] = df.as[Person] // DataFrame → DataSet (类型安全)
val df3: DataFrame = ds.toDF()           // DataSet → DataFrame

三、RDD vs DataFrame vs DataSet 对比

维度 RDD DataFrame DataSetT
版本 Spark 1.0 Spark 1.3 Spark 1.6
Schema ❌ ✅ ✅
类型安全 ✅ 编译期 ❌ 运行时 ✅ 编译期
优化器 ❌ ✅ Catalyst ✅ Catalyst
序列化 Java/Kryo Encoder (Tungsten) Encoder (Tungsten)
API 风格 函数式 SQL/DSL 函数式+SQL
Python ✅ ✅ ❌ (仅 Scala/Java)
推荐度 特殊场景 快速分析 ⭐ 生产首选

四、DataFrame 实操

4.1 创建 DataFrame

scala 复制代码
// 方式 1: 从 JSON/CSV/Parquet 读取
val df = spark.read.json("hdfs:///data/people.json")
val df2 = spark.read.option("header", "true").csv("hdfs:///data/people.csv")

// 方式 2: 从 RDD + Schema 创建
val rdd = spark.sparkContext.parallelize(Seq(
  ("Alice", 28), ("Bob", 35), ("Charlie", 42)
))
val df3 = rdd.toDF("name", "age")

// 方式 3: SQL 查询
df.createOrReplaceTempView("people")
val df4 = spark.sql("SELECT name, age FROM people WHERE age > 30")

4.2 DataFrame 操作

scala 复制代码
// DSL 风格
df.select($"name", $"age" + 1)
  .where($"age" > 30)
  .groupBy($"name")
  .agg(avg($"age").as("avg_age"))
  .orderBy($"avg_age".desc)
  .show()

// SQL 风格
spark.sql("""
  SELECT name, AVG(age) as avg_age
  FROM people WHERE age > 30
  GROUP BY name ORDER BY avg_age DESC
""")

五、DataSet 实操(类型安全)

scala 复制代码
// 定义 case class
case class Person(name: String, age: Int)

// 从 DataFrame 转 DataSet
import spark.implicits._
val ds: DataSet[Person] = df.as[Person]

// DataSet 类型安全操作
ds.filter(_.age > 30)           // 编译期检查:_.age 是 Int
  .map(p => (p.name, p.age + 1)) // 类型安全的 map
  .groupByKey(_._1)
  .agg(avg($"_2").as[Double])
  .show()

六、Encoder 序列化(比 Kryo 快)

scala 复制代码
// Encoder 自动生成(case class)
val ds = spark.read.json("...").as[Person]
// 内部使用 Tungsten 堆外内存 + 二进制格式 → 免 Java/Kryo 序列化

// 显式创建 Encoder
import org.apache.spark.sql.Encoders
val encoder = Encoders.product[Person]
val ds2 = spark.createDataset(Seq(Person("A", 1)))(encoder)

七、Catalyst 优化器四阶段

java 复制代码
SQL/DSL 文本 → ① Parser → Unresolved Logical Plan
            → ② Analyzer → Resolved Logical Plan (绑定表/列)
            → ③ Optimizer → Optimized Logical Plan (谓词下推/列裁剪)
            → ④ Planner → Physical Plan (RDD DAG)

八、生产最佳实践

bash 复制代码
# 推荐: DataSet[T] (Scala) / DataFrame (Python)
# 配置关键参数
--conf spark.sql.adaptive.enabled=true
--conf spark.sql.shuffle.partitions=200
--conf spark.sql.autoBroadcastJoinThreshold=10MB
--conf spark.sql.parquet.filterPushdown=true

九、总结

要点 总结
入口 SparkSession 替代 SQLContext
DataFrame = DataSetRow,有 Schema 无类型
DataSet = RDD + Encoder + Catalyst,生产首选
Encoder Tungsten 堆外,比 Kryo 更快
Python 只有 DataFrame,无 DataSet

金句:RDD 给了你灵活的自由,DataFrame 给了你 SQL 的优雅,DataSet 给了你编译期的安全------三者是一个进化链,而不是互斥的选项。


作者:starzy | AI Data Engineer / 大数据技术实践者

博客:blog.starzy.cn | GitHub:starzy1990.github.io

专注 AI Agent · LangGraph · RAG · 大数据架构 · 数据工程实践

相关推荐
国际学术会议-杨老师1 分钟前
2027年人文发展、城市管理与数字化社会国际会议(HUCD 2027)
大数据·人工智能·人文发展
科技每日热闻11 分钟前
电气设备综合维保服务商怎么选?从预防性维护到数字化运维,看懂五个关键能力——企业选择维保合作伙伴,不能只看“坏了能不能修”,更要看能否覆盖资产与系统的长期运营
大数据·运维·人工智能
电子制造自留地29 分钟前
AI服务器高多层PCB设计:阻抗控制、层间对位与孔金属化工程要点
大数据·网络·人工智能·科技·pcb工艺
星云低代码开发平台34 分钟前
ERP 与 CRM 客户信用核对:业务键、时点和权限验收
大数据·数据库·人工智能
xiaogai_gai44 分钟前
销售出库单同步实战:旺店通→金蝶云星空的单一策略深度拆解
大数据·前端·数据库
guhunyihan1 小时前
零代码快速搭建平台典型应用场景,恐象 AI 落地能力分析
大数据·人工智能
什么嘻嘻果冻1 小时前
无代码开发平台中的自然语言生成:恐象AI实现路径
大数据·人工智能·低代码
cspttty2 小时前
2027秋招市场调研岗:统计学专业如何补齐业务、SQL与研究交付能力
大数据·数据库
AOI小白新手上路2 小时前
autodl无卡模式下载NTURain 训练集实录:基于 Git 部分克隆与稀疏检出的数据拉取
大数据·git·elasticsearch