Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/256.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Dataframe 是否有一种惯用的方式来缓存Spark数据帧?_Dataframe_Apache Spark_Pyspark_Apache Spark Sql - Fatal编程技术网

Dataframe 是否有一种惯用的方式来缓存Spark数据帧?

Dataframe 是否有一种惯用的方式来缓存Spark数据帧?,dataframe,apache-spark,pyspark,apache-spark-sql,Dataframe,Apache Spark,Pyspark,Apache Spark Sql,我有一个很大的拼花地板数据集,我正在与Spark一起阅读。读取后,我将筛选应用不同转换的许多函数中使用的行子集: 以下内容与我试图完成的内容类似,但并不完全符合逻辑: df = spark.read.parquet(file) special_rows = df.filter(col('special') > 0) # Thinking about adding the following line special_rows.cache() def f1(df): new_df_1

我有一个很大的拼花地板数据集,我正在与Spark一起阅读。读取后,我将筛选应用不同转换的许多函数中使用的行子集:

以下内容与我试图完成的内容类似,但并不完全符合逻辑:

df = spark.read.parquet(file)
special_rows = df.filter(col('special') > 0)

# Thinking about adding the following line
special_rows.cache()

def f1(df):
  new_df_1 = df.withColumn('foo', lit(0))
  return new_df_1

def f2(df):
  new_df_2 = df.withColumn('foo', lit(1))
  return new_df_2

new_df_1 = f1(special_rows)
new_df_2 = f2(special_rows)
output_df = new_df_1.union(new_df_2)
output_df.write.parquet(location)
因为许多函数可能正在使用这个过滤的行子集,所以我想缓存或持久化它,以潜在地加快执行速度/内存消耗。我知道在上面的例子中,在我最后一次写入
parquet
之前,没有调用任何操作

我的问题是,我是否需要插入某种对
count()
的调用,例如,为了触发缓存,或者Spark在最后一次对parquet的写入调用中是否能够看到此数据帧正在
f1
f2
中使用,并将缓存数据帧本身

如果是,这是惯用的方法吗?这是否意味着在依赖缓存的生产和大规模Spark作业中,经常使用强制数据帧上的操作的随机操作,例如调用
计数

在我最后一次写信给拼花地板之前,我不会采取任何行动

Spark在最后一次写入parquet调用期间将能够看到此数据帧正在f1和f2中使用,并将缓存数据帧本身

你说得对。如果您执行
output\u df.explain()
,您将看到查询计划,它将显示您所说的是正确的


因此,不需要执行
特殊的\u rows.cache()
。一般来说,
cache
仅在您打算在强制Spark计算某项内容后重新使用数据帧时才有必要,例如在
写入
显示
之后。如果您看到自己故意调用
count()
,则可能是做错了什么。

您可能希望在运行
special\u rows=df.filter(col('special')>0)后重新分区。运行筛选操作后,可能会有大量空分区

new_-dfu-1
将生成缓存
特殊行
,这些行将被
new_-dfu-2
此处的
new_-dfu-1.union(new_-dfu-u-2)
重用。这不一定是性能优化。缓存是昂贵的。我已经看到缓存会降低很多计算速度,即使它是以教科书的方式使用的(即缓存一个在下游多次重复使用的数据帧)

计数不一定确保数据被缓存。计数尽可能避免扫描行。他们会在可能的时候使用拼花地板元数据,这意味着他们不会像您预期的那样缓存所有数据

您还可以通过将数据写入磁盘来“缓存”数据。大概是这样的:

df.filter(col('special')>0)。重新分区(500)。write.parquet(“某些路径”)
特殊行=spark.read.parquet(“某些路径”)

总而言之,是的,在本例中数据帧将被缓存,但它不一定会使您的计算运行得更快。最好不要缓存,或者通过将数据写入磁盘来“缓存”。

谢谢@mck!作为一个快速的跟进,如果我想让这个子集数据帧也潜在地持久化到磁盘上呢?我需要使用persist()调用吗?我将立即查看查询计划,但我正在尝试先发制人地解决一个大型Spark应用程序将缓存大量大数据帧的情况。如果您还将保存到parquet new_df_1和new_df_2,那么您应该按照您所说的使用缓存。