DataFrame/Dataset API 详解(以 Spark 3.x 为例)

DataFrame/Dataset API 详解(以 Spark 3.x 为例)

DataFrame 和 Dataset 是 Spark 结构化数据处理的核心抽象,基于 Spark SQL 引擎构建,提供高性能、类型安全的操作。二者共享大部分 API(DataFrame = Dataset[Row])。


一、核心概念

  1. DataFrame

    • 分布式数据集合,按命名列组织(类似关系型数据库表)
    • 弱类型(运行时类型检查)
    • 优化器自动优化执行计划
  2. Dataset (Scala/Java)

    • 强类型 API(编译时类型安全)
    • 需定义 case class 或 JavaBean
    case class Person(name: String, age: Int)
    val ds: Dataset[Person] = spark.read.json("path").as[Person]
    

二、创建 DataFrame/Dataset

数据源示例代码
JSON 文件spark.read.json("data.json")
CSV 文件spark.read.option("header",true).csv("data.csv")
Parquet 文件spark.read.parquet("data.parquet")
RDD 转换rdd.toDF("col1","col2")
Hive 表spark.sql("SELECT * FROM hive_table")

三、核心操作分类

1. 转换操作(Transformations)
(1) 列操作
API说明示例
select()选择列df.select($"name", $"age" + 1)
withColumn()添加/替换列df.withColumn("age2", $"age" * 2)
drop()删除列df.drop("temp_col")
cast()类型转换df.withColumn("age", $"age".cast("int"))
(2) 过滤
API示例
filter()df.filter($"age" > 30)
where()df.where($"salary" < 5000)
(3) 聚合
API说明示例
groupBy()分组df.groupBy("department")
agg()聚合函数grouped.agg(avg($"salary"), max($"age"))
rollup()多维聚合df.rollup("city", "year").sum("revenue")
(4) 连接
类型API
内连接df1.join(df2, $"id1" === $"id2")
左外连接df1.join(df2, Seq("id"), "left_outer")
交叉连接df1.crossJoin(df2)
(5) 窗口函数
import org.apache.spark.sql.expressions.Window
val window = Window.partitionBy("dept").orderBy($"salary".desc)
df.withColumn("rank", rank().over(window))
2. 行动操作(Actions)
API说明
show()打印前 n 行(默认 20)
count()返回行数
collect()返回所有数据到 Driver(慎用)
write.save()写入数据源

四、高级特性

1. UDF(用户自定义函数)
# Python 示例
from pyspark.sql.functions import udf
from pyspark.sql.types import IntegerType

add_one = udf(lambda x: x + 1, IntegerType())
df.select(add_one($"age"))
2. Catalyst 优化器
  • 逻辑优化:谓词下推、常量折叠等
  • 物理优化:选择最优 Join 策略
3. Tungsten 执行引擎
  • 堆外内存管理
  • 代码生成(Code Generation)

五、执行计划查看

df.explain()  // 查看物理计划
df.explain(extended = true)  // 逻辑+物理计划

六、数据写入

df.write
  .format("parquet")        // 格式: json/csv/orc...
  .mode("overwrite")        // 模式: append/ignore/error
  .option("path", "output/")
  .save()

七、性能优化技巧

  1. 分区剪枝(Partition Pruning)
    spark.read.parquet("/data/year=2023/month=08")
    
  2. 谓词下推(Predicate Pushdown)
    自动将过滤条件下推到数据源层
  3. 缓存常用数据
    df.cache()  // 或 df.persist(StorageLevel.MEMORY_AND_DISK)
    

八、对比 RDD API

特性DataFrame/DatasetRDD
优化Catalyst 自动优化手动优化
序列化Tungsten 二进制Java 序列化
API声明式过程式
类型结构化/半结构化任意数据

最佳实践:优先使用 DataFrame API,需要类型安全时用 Dataset,避免混合 RDD 操作以确保优化器生效。

通过这套 API,Spark 在保持易用性的同时,实现了接近手写代码的性能,特别适合大规模数据批处理和流处理场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值