RDD、dataframe和dateset区别
这三个是 Spark 里的核心数据抽象,很多人会混淆。我们来逐层对比一下:
1. 概念对比
特性 | RDD (Resilient Distributed Dataset) | DataFrame | Dataset |
---|---|---|---|
提出时间 | Spark 最早的数据抽象 (Spark 1.0 就有) | Spark 1.3 引入 | Spark 1.6 引入 |
数据结构 | 分布式对象集合(强类型,但无 schema) | 分布式表格数据(有 schema,类似数据库表) | 介于两者之间:既有类型安全(编译期检查),也有 schema |
API 风格 | 函数式编程风格 (map, filter, reduce, flatMap...) | 类 SQL 风格 (select, groupBy, agg...) | 同时支持函数式操作 + SQL 风格 |
类型安全 | 有(但元素都是 JVM 对象,缺乏 schema 信息) | 无(只有运行时 schema,编译时不检查) | 有(编译器可检查字段,避免拼写错误等) |
优化能力 | 无优化,纯计算图 (DAG) | Catalyst 优化器可以优化查询计划 | Catalyst 优化器 + Encoders(序列化优化) |
序列化 | Java 序列化或 Kryo,开销大 | 内部用 Tungsten(更高效的二进制内存表示) | 同 DataFrame(Tungsten),但额外支持类型安全的 Encoders |
使用场景 | 复杂底层转换逻辑,非结构化数据 | 结构化数据处理,大规模 SQL 查询 | 需要既有类型安全又有高性能结构化计算 |
2. 举例说明
假设有订单数据 (orderNo: String, cost: Long)
:
RDD
👉 特点:面向对象,灵活,但没有 schema,不能用 SQL。
DataFrame
👉 特点:有 schema,可以直接用 SQL/DSL,很简洁,但编译器不会检查字段名拼写。
Dataset
Encoder<Order> orderEncoder = Encoders.bean(Order.class); Dataset<Order> ds = spark.read().json("orders.json").as(orderEncoder); Dataset<Row> result = ds.groupBy("orderNo") .agg(functions.sum("cost").alias("totalCost")); result.show();
👉 特点:有 schema,且 Order
是强类型,拼写错误会在编译时报错。
3. 总结类比
-
RDD:像一堆 Java 对象集合,灵活但「裸奔」,没有 schema,优化弱。
-
DataFrame:像数据库表,有 schema,可以写 SQL,优化强,但无类型安全。
-
Dataset:折中方案,有 schema + 类型安全,结合 RDD 和 DataFrame 的优势。
📌 一句话总结:
-
需要灵活复杂操作 → RDD
-
主要做结构化计算、SQL → DataFrame
-
想要类型安全 + 结构化查询 → Dataset(Java/Scala 推荐)