Spark RDD 和 DataSet

引言

看DataSet完整类名:org.apache.spark.sql.DataSet, 会认为它只是处理DB数据才用到,大概类似java.sql.ResultSet, 只是它支持分布式并行计算。其实不然。

RDD

RDD是最初最核心的Spark对象。整个Spark的分布式计算能力就体现在RDD的定义上。
通常在以下场景使用RDD:

  1. 对数据集做最基础的transform(如map, filter, combineByKey) 和 action (take,max,count,persist)
  2. 针对的是非结构性数据,比如raw文本流
  3. 不太关注数据域,不常以数据域来做数据处理
  4. 通常性能上,比DataSet要好些,也就是说,使用DataSet的代码,可以性能优化为RDD的代码

DataSet

其实DataSet是构建在RDD之上的,为了便于处理结构性数据(或半结构)。应该是受R和Python相应的启发,而加入的。
通常在以下场景使用DataSet:

  1. 处理的数据是结构性的(半结构)
  2. DB数据,包括RDBMS,Cassandra/Hbase等NoSQL
  3. 代码语义化
  4. 高性能列处理,如parquet
case class Person(name: String, age: Long)
val personDs = spark.read.json("/path/to/spark-source/examples/src/main/resources/people.json").as[Person]

也可以由RDD转换而来:

  spark.sparkContext
  .textFile("/path/to/spark-source/examples/src/main/resources/people.json")
  .map(_.split(","))
  .map(attributes => Person(attributes(0), attributes(1).trim.toInt)).toDF

至于DataFrame, 看定义type DataFrame = DataSet[Row] 就知道了,它其实使用了内置的通用数据结构Row的DataSet,也就是untyped:

case class Person(name: String, age: Long)
val personDs = spark.read.json("/path/to/spark-source/examples/src/main/resources/people.json")

需要注意的是,DataFrame在 compile time 的分析检查比较弱,可能会增加调试时间,也会增加更多runtime异常。特别是spark.sql()

另外,DataSet和DataFrame底层是会将语句优化生成一个logical plan,也就是会有一个执行优化的过程,性能上也不会输于RDD多少。

后记

个人觉得 spark-sql 本身就是特指db sql,而是更本质的结构性的数据处理(structured data procecssing)

Back to top

comments powered by Disqus