scala 为什么dataset.count()比rdd.count()快?

rvpgvaaj  于 2023-06-23  发布在  Scala
关注(0)|答案(2)|浏览(138)

我创建了一个Spark Dataset[Long]

scala> val ds = spark.range(100000000)
ds: org.apache.spark.sql.Dataset[Long] = [id: bigint]

当我运行ds.count时,它给我的结果是0.2s(在4核8GB机器上)。此外,它创建的DAG如下所示:

但是,当我运行ds.rdd.count时,它给我的结果是4s(同一台机器)。但它创建的DAG如下:

所以,我的疑虑是:
1.为什么ds.rdd.count只创建一个阶段,而ds.count创建两个阶段?
1.另外,当ds.rdd.count只有一个阶段时,为什么它比有两个阶段的ds.count慢?

ruarlubt

ruarlubt1#

为什么ds.rdd.count只创建一个阶段,而ds.count创建两个阶段?
两个计数实际上是两步操作。不同之处在于,在ds.count的情况下,最终聚合由执行器之一执行,而ds.rdd.count聚合驱动程序上的最终结果,因此该步骤未反映在DAG中:
另外,当ds.rdd.count只有一个阶段时,为什么它会更慢
同样,ds.rdd.count必须初始化(以及稍后的垃圾收集)1亿个Row对象,这几乎不是免费的,可能是这里大部分时间差的原因。
最后,类range对象不是一个好的基准测试工具,除非非常谨慎地使用。根据上下文计数,范围内的操作可以表示为常数时间操作,即使没有显式优化也可以非常快(例如,参见spark.sparkContext.range(0, 100000000).count),但不能反映真实的工作负载的性能。
标签:How to know which count query is the fastest?

相关问题