我是否必须显式使用 Dataframe 的方法来利用 Dataset 的优化?
Do I have to explicitly use Dataframe's methods to take advantage of Dataset's optimization?
要利用 Dataset
的优化,我是否必须明确使用 Dataframe's
方法(例如 df.select(col("name"), col("age")
等)或调用 any Dataset 的方法 - even RDD-like methods (e.g. filter
, map
, etc) 也可以优化?
Dataframe 优化通常有 3 种形式:
- Tungsten 内存管理
- Catalyst 查询优化
- wholestage codegen
Tungsten 内存管理
在定义RDD[myclass]时,spark并没有真正理解myclass是什么。这意味着通常每行将包含 class 的一个实例。
这有两个问题。
首先是对象的大小。 java 对象有开销。例如,包含两个简单整数的案例 class。执行一系列 1000000 个实例并将其转换为 RDD 将花费约 26MB,而使用 dataset/dataframe 执行相同操作将花费约 2MB。
此外,此内存在 dataset/dataframe 中完成后不受垃圾收集管理(它在内部由 spark 管理为不安全内存),因此 GC 性能的开销较小。
Dataset享有与DataFrame相同的内存管理优势。也就是说,在进行数据集操作时,将数据从内部(行)数据结构转换为 case class 会产生性能开销。
Catalyst 查询优化
当使用数据框函数时,spark 知道您要做什么,有时可以将您的查询修改为更高效的等效查询。
例如,假设您正在做类似的事情:
df.withColumn("a",lit(1)).filter($"b" < ($"a" + 1)).
基本上你是在检查是否 (x < 1 + 1)。 Spark 足够聪明,可以理解这一点并将其更改为 x<2.
使用数据集操作时无法完成此类操作,因为 spark 不了解您正在执行的函数的内部结构。
wholestage codegen
当 spark 知道您在做什么时,它实际上可以生成更高效的代码。在某些情况下,这可以将性能提高 10 倍。
这也不能在数据集函数上完成,因为 spark 不知道函数的内部结构。
要利用 Dataset
的优化,我是否必须明确使用 Dataframe's
方法(例如 df.select(col("name"), col("age")
等)或调用 any Dataset 的方法 - even RDD-like methods (e.g. filter
, map
, etc) 也可以优化?
Dataframe 优化通常有 3 种形式:
- Tungsten 内存管理
- Catalyst 查询优化
- wholestage codegen
Tungsten 内存管理
在定义RDD[myclass]时,spark并没有真正理解myclass是什么。这意味着通常每行将包含 class 的一个实例。
这有两个问题。
首先是对象的大小。 java 对象有开销。例如,包含两个简单整数的案例 class。执行一系列 1000000 个实例并将其转换为 RDD 将花费约 26MB,而使用 dataset/dataframe 执行相同操作将花费约 2MB。
此外,此内存在 dataset/dataframe 中完成后不受垃圾收集管理(它在内部由 spark 管理为不安全内存),因此 GC 性能的开销较小。
Dataset享有与DataFrame相同的内存管理优势。也就是说,在进行数据集操作时,将数据从内部(行)数据结构转换为 case class 会产生性能开销。
Catalyst 查询优化
当使用数据框函数时,spark 知道您要做什么,有时可以将您的查询修改为更高效的等效查询。
例如,假设您正在做类似的事情: df.withColumn("a",lit(1)).filter($"b" < ($"a" + 1)).
基本上你是在检查是否 (x < 1 + 1)。 Spark 足够聪明,可以理解这一点并将其更改为 x<2.
使用数据集操作时无法完成此类操作,因为 spark 不了解您正在执行的函数的内部结构。
wholestage codegen
当 spark 知道您在做什么时,它实际上可以生成更高效的代码。在某些情况下,这可以将性能提高 10 倍。
这也不能在数据集函数上完成,因为 spark 不知道函数的内部结构。