Apache spark 正在缓存后重新评估Spark数据帧

Apache spark 正在缓存后重新评估Spark数据帧,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,我在使用spark数据帧上的缓存时遇到了一些问题。我的期望是,在对数据帧进行缓存之后,会在第一次需要时创建并缓存数据帧。对数据帧的任何进一步调用都应该来自缓存 这是我的密码: val mydf = spark.sql("read about 400 columns from a hive table"). withColumn ("newcol", someudf("existingcol")). cache() 为了进行测试,我运行了两次mydf.count()。我希望第一次需要一些

我在使用spark数据帧上的缓存时遇到了一些问题。我的期望是,在对数据帧进行缓存之后,会在第一次需要时创建并缓存数据帧。对数据帧的任何进一步调用都应该来自缓存

这是我的密码:

val mydf = spark.sql("read about 400 columns from a hive table").
  withColumn ("newcol", someudf("existingcol")).
  cache()
为了进行测试,我运行了两次mydf.count()。我希望第一次需要一些时间,因为数据正在缓存。但是第二次应该是瞬间的吗

我实际上看到的是,两次计数所用的时间是相同的。第一个很快就回来了,我想这告诉我数据没有被缓存。如果我删除代码的withColumn部分并缓存原始数据,则第二次计数是瞬时的

我做错什么了吗?如何从配置单元加载原始数据,添加列,然后缓存数据帧以供进一步使用?使用spark 2.3


任何帮助都会很好

缓存数据集/数据帧时,请执行以下操作:

def cache():Dataset.this.type

使用默认存储级别(
内存和磁盘
)保留此数据集

所以你可以试试看

def persist(newLevel:StorageLevel):Dataset.this.type

使用给定的存储级别持久化此数据集

newLevel
其中之一:
MEMORY\u ONLY
MEMORY\u AND\u DISK
MEMORY\u ONLY\u SER
MEMORY\u AND\u DISK\u SER
MEMORY\u ONLY\u 2
MEMORY\u AND\u DISK\u 2
,等等


缓存数据集/数据帧时,请执行以下操作:

def cache():Dataset.this.type

使用默认存储级别(
内存和磁盘
)保留此数据集

所以你可以试试看

def persist(newLevel:StorageLevel):Dataset.this.type

使用给定的存储级别持久化此数据集

newLevel
其中之一:
MEMORY\u ONLY
MEMORY\u AND\u DISK
MEMORY\u ONLY\u SER
MEMORY\u AND\u DISK\u SER
MEMORY\u ONLY\u 2
MEMORY\u AND\u DISK\u 2
,等等


您案例中的问题是
mydf.count()
实际上并没有具体化数据帧(即,并非所有列都被读取,您的udf将不会被调用)。这是因为
count()
是高度优化的

为了确保将整个数据帧缓存到内存中,您应该使用
mydf.rdd.count()
或其他查询(例如使用排序和/或聚合)重复您的实验


例如,请参见

您案例中的问题是,
mydf.count()
实际上并没有具体化数据帧(即,并非所有列都被读取,您的udf将不会被调用)。这是因为
count()
是高度优化的

为了确保将整个数据帧缓存到内存中,您应该使用
mydf.rdd.count()
或其他查询(例如使用排序和/或聚合)重复您的实验


例如,请参见

是否可以检查explainPlan()中的数据和Spark UIs存储选项卡,以查看数据是否实际持久化?是否可以检查explainPlan()中的数据和Spark UIs存储选项卡,以查看数据是否实际持久化?这没有什么区别。我也试过运行agg,多个查询的响应时间保持不变。我能让它快速工作的唯一方法是删除withColumn,但我需要它,这没有什么区别。我也试过运行agg,多个查询的响应时间保持不变。唯一能让它快速工作的方法是删除withColumn,但我需要它