SparkSQL: intra-SparkSQL-application table registration



Context.我有数十个SQL查询存储在单独的文件中。出于基准测试的目的,我创建了一个应用程序,用于循环访问每个查询文件并将其传递给独立的 Spark 应用程序。后者首先解析查询,提取使用的表,注册它们(使用:Spark <2 中的registerTempTable()和 Spark 2 中的createOrReplaceTempView()(,并有效地执行查询(spark.sql()(。

挑战。由于注册表可能很耗时,因此我想懒惰地注册表,即在首次使用表时仅注册一次,并将其保留为元数据的形式,以便在后续查询中轻松使用,而无需为每个查询重新注册表。据我所知,这是一种作业内缓存,但不是 Spark 提供的任何缓存选项(表缓存(。

这可能吗? 如果不是,任何人都可以建议另一种方法来实现相同的目标(循环访问单独的查询文件并运行查询 Spark 应用程序,而无需注册之前已注册的表(。

通常,注册表不应花费时间(除非有大量文件,生成文件源列表可能需要一些时间(。它基本上只是给数据帧一个名字。从磁盘读取数据帧需要时间。

所以基本问题是,数据帧(表(是如何写入磁盘的。如果它被写成大量的小文件或文件格式很慢(例如.csv(,这可能需要一些时间(有很多文件需要时间来生成文件列表,并且具有"慢"文件格式意味着实际读取很慢(。

因此,您可以尝试做的第一件事是读取数据并重新保存。例如,假设您在某个路径中有大量CSV文件。您可以执行以下操作:

 df = spark.read.csv("path/*.csv")

现在您已经有了数据帧,您可以将其更改为包含更少的文件并使用更好的格式,例如:

df.coalesce(100).write.parquet("newPath")

如果上述还不够,并且您的集群足够大,可以缓存所有内容,则可以将所有内容放在单个作业中,遍历所有查询中的所有表,注册所有表并缓存它们。然后一个接一个地运行你的sql查询(并分别对每个查询进行计时(。

如果所有这些都失败了,你可以尝试使用alluxio(http://www.alluxio.org/(之类的东西来创建一个内存文件系统,并尝试从中读取。

相关内容

  • 没有找到相关文章