DataSet相对于RDD的性能优势

VB_*_*VB_ 3 apache-spark rdd apache-spark-dataset

在阅读了几篇关于Spark的DataSet的精彩文章(,本文)后,我完成了下一个DataSet相对于RDD的性能优势:

  1. 逻辑和物理计划优化;
  2. 严格的典型化;
  3. 矢量化操作;
  4. 低级内存管理.

问题:

  1. Spark的RDD还可以构建物理计划,并可以在同一阶段组合/优化多个转换.那么DataSet相对于RDD有什么好处呢?
  2. 第一个链接可以看到一个例子RDD[Person].DataSet是否具有高级典型化?
  3. "矢量化操作"是什么意思?
  4. 据我了解,DataSet的低内存管理=高级序列化.这意味着可序列化对象的堆外存储,您可以在其中只读取对象的一个​​字段而不进行反序列化.但是当你有IN_MEMORY_ONLY持久性策略时,情况怎么样?无论如何,DataSet会将所有内容序列化吗?它会比RDD有任何性能优势吗?

use*_*411 5

Spark的RDD还可以构建物理计划,并可以在同一阶段组合/优化多个转换.比DataSet优于RDD的好处是什么?

使用RDD时,您所写的就是您所获得的.虽然通过链接优化了某些转换,但执行计划是DAG的直接转换.例如:

rdd.mapPartitions(f).mapPartitions(g).mapPartitions(h).shuffle()
Run Code Online (Sandbox Code Playgroud)

其中shuffle是任意的混洗变换(*byKey,repartition等)的所有三个mapPartitions(map,flatMap,filter)将被而不创建中间对象,但不能被重新排列链.

Datasets使用明显更具限制性的编程模型相比,可以使用多种技术优化执行,包括:

这些优化可能有两个原因:

  • 限制性数据模型,无需复杂和不可靠的静态代码分析即可实现依赖性分析.
  • 清除运算符语义.运算符是免费的副作用,我们清楚地区分确定性和非确定性.

为了说清楚,我们假设我们有以下数据模型:

case class Person(name: String, surname: String, age: Int)

val people: RDD[Person] = ???
Run Code Online (Sandbox Code Playgroud)

我们想要检索21岁以上所有人的姓氏.RDD它可以表示为:

people
  .map(p => (p.surname, p.age))          // f
  .filter { case (_, age) => age > 21 }  // g
Run Code Online (Sandbox Code Playgroud)

现在让我们问自己一些问题:

  • 什么是输入之间的关系,agefage变量,g
  • f然后g一样g然后f呢?
  • fg副作用是免费的吗?

虽然答案对于人类读者来说是显而易见的,但它不适用于假设的优化器.与Dataframe版本相比:

people.toDF
  .select(col("surname"), col("age"))    // f'
  .where(col("age") > 21)                // g'
Run Code Online (Sandbox Code Playgroud)

优化者和人类读者的答案都很明确.

当使用静态类型Datasets(Spark 2.0 Dataset vs DataFrame)时,这会产生一些进一步的后果.

DataSet有更先进的典型化吗?

  • 不 - 如果你关心优化.最高级的优化仅限于Dataset[Row]此时,不可能对复杂类型层次结构进行编码.
  • 也许 - 如果您接受Kryo或Java编码器的开销.

它们对"矢量化操作"意味着什么?

在优化的上下文中,我们通常意味着循环矢量化/循环展开.Spark SQL使用代码生成来创建高级转换的编译器友好版本,可以进一步优化以利用向量化指令集.

据我了解,DataSet的低内存管理=高级序列化.

不完全是.使用本机分配的最大优点是转义垃圾收集器循环.由于垃圾收集通常是Spark中的一个限制因素,因此这是一个巨大的改进,特别是在需要大型数据结构(如准备shuffle)的环境中.

另一个重要方面是柱状存储,它可以实现有效压缩(可能更低的内存占用)和对压缩数据的优化操作.

通常,您可以在plain上使用手工制作的代码应用完全相同类型的优化RDDs.毕竟Datasets得到了支持RDDs.不同之处仅在于需要多少努力.

  • 手工制作的执行计划优化实现起来相对简单.
  • 使代码编译器友好需要一些更深入的知识,并且容易出错并且冗长.
  • 使用sun.misc.Unsafe本机内存分配不适合胆小的人.

尽管它的所有优点DatasetAPI并不普及.虽然某些类型的常见任务可以在许多情况下从其优化中受益,但与RDD等效项相比,您可能无论如何都没有任何改进甚至性能下降.