VB_*_*VB_ 3 apache-spark rdd apache-spark-dataset
在阅读了几篇关于Spark的DataSet的精彩文章(本,本和本文)后,我完成了下一个DataSet相对于RDD的性能优势:
问题:
RDD[Person].DataSet是否具有高级典型化?IN_MEMORY_ONLY持久性策略时,情况怎么样?无论如何,DataSet会将所有内容序列化吗?它会比RDD有任何性能优势吗?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使用明显更具限制性的编程模型相比,可以使用多种技术优化执行,包括:
选择(filter)下推.例如,如果你有:
df.withColumn("foo", col("bar") + 1).where(col("bar").isNotNull())
Run Code Online (Sandbox Code Playgroud)
可以执行为:
df.where(col("bar").isNotNull()).withColumn("foo", col("bar") + 1)
Run Code Online (Sandbox Code Playgroud)早期预测(select)和抵消.例如:
df.withColumn("foo", col("bar") + 1).select("foo", "bar")
Run Code Online (Sandbox Code Playgroud)
可以改写为:
df.select("foo", "bar").withColumn("foo", col("bar") + 1)
Run Code Online (Sandbox Code Playgroud)
避免获取和传递过时的数据.在极端情况下,它可以完全消除特定的转换:
df.withColumn("foo", col("bar") + 1).select("bar")
Run Code Online (Sandbox Code Playgroud)
可以优化到
df.select("bar")
Run Code Online (Sandbox Code Playgroud)这些优化可能有两个原因:
为了说清楚,我们假设我们有以下数据模型:
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)
现在让我们问自己一些问题:
age在f和age变量,g?f然后g一样g然后f呢?f和g副作用是免费的吗?虽然答案对于人类读者来说是显而易见的,但它不适用于假设的优化器.与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]此时,不可能对复杂类型层次结构进行编码.它们对"矢量化操作"意味着什么?
在优化的上下文中,我们通常意味着循环矢量化/循环展开.Spark SQL使用代码生成来创建高级转换的编译器友好版本,可以进一步优化以利用向量化指令集.
据我了解,DataSet的低内存管理=高级序列化.
不完全是.使用本机分配的最大优点是转义垃圾收集器循环.由于垃圾收集通常是Spark中的一个限制因素,因此这是一个巨大的改进,特别是在需要大型数据结构(如准备shuffle)的环境中.
另一个重要方面是柱状存储,它可以实现有效压缩(可能更低的内存占用)和对压缩数据的优化操作.
通常,您可以在plain上使用手工制作的代码应用完全相同类型的优化RDDs.毕竟Datasets得到了支持RDDs.不同之处仅在于需要多少努力.
sun.misc.Unsafe本机内存分配不适合胆小的人.尽管它的所有优点DatasetAPI并不普及.虽然某些类型的常见任务可以在许多情况下从其优化中受益,但与RDD等效项相比,您可能无论如何都没有任何改进甚至性能下降.
| 归档时间: |
|
| 查看次数: |
531 次 |
| 最近记录: |