2016-11-11 44 views
1

语境。我有数十个SQL查询存储在单独的文件中。为了进行基准测试,我创建了一个遍历每个查询文件并将其传递给独立Spark应用程序的应用程序。这后一种首先解析查询,提取中使用的表,将它们登记(使用:在registerTempTable()火花< 2和createOrReplaceTempView()在火花2),和有效地执行该查询(spark.sql())。SparkSQL:帧内SparkSQL应用表登记

挑战。由于登记表可以是耗时的,我想懒惰地注册的表中,即,仅一次当它们用于第一,并保持在元数据的形式,可以容易地在随后的查询中使用而无需为每个查询重新注册表格。就我所知,这是一种内部作业缓存,但没有提供Spark提供的任何缓存选项(表缓存)。

这可能吗?如果没有人可以提出另一种方法来实现相同的目标(遍历单独的查询文件并运行查询Spark应用程序,而无需注册之前已经注册的表)。

+0

我对我自己的问题发表评论。我遇到了由[Spark Job Server]提供的命名RDD /对象(https://github.com/spark-jobserver/spark-jobserver#named-objects)。还没有自己尝试过,但未来任何人通过这个问题可能想看看这个。 –

回答

0

一般来说,登记表应该不花时间(除非你有很多的文件,可能需要一段时间才能生成的文件源列表)。它基本上只是给数据框命名。需要花费时间的是从磁盘读取数据帧。

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

所以,你可以尝试做的第一件事就是阅读你的数据,并重新保存它。 可以说为了示例的目的,您在某个路径中有大量的csv文件。你可以这样做:

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

现在你有一个数据框,你可以改变它具有较小的文件,并使用更好的格式,如:

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

如果上面是不够的,您的集群足够大以缓存所有内容,您可以将所有内容放在一个作业中,在所有查询中查看所有表,并将其全部注册并缓存。然后依次运行你的SQL查询(和每个单独的时间)。

如果所有这些都失败了,您可以尝试使用像alluxio(http://www.alluxio.org/)这样的内容来创建内存文件系统并尝试从中读取。

+0

谢谢阿萨夫。实际上,每张桌子都保存为一张Parquet桌子,所以文件并不多。即使如此,我仍然需要一些时间来进行一些查询。我监视了表的注册,我可以告诉他们,对于一些查询,他们需要时间,当然它仍然是几秒钟的规模,但对于交互式查询,这已经很长了 - 对于某些查询,它需要相同的或者甚至比执行查询花费的时间还要多。 –

+0

此外,实际上我可以把所有东西都放在一个单独的工作中,并且应该被削减,但是这违背了我们的基准测试协议,执行工作应该是一个独立的(Spark)应用程序,它将数据库的路径作为参数)以及针对后者数据库执行的查询,并且通过Shell脚本完成对SQL查询文件的迭代。因此,我正在寻求帮助/指导。 –