如何在Spark中更有效地加载Parquet文件(pySpark v1.2.0)

时间:2015-04-22 16:33:17

标签: apache-spark apache-spark-sql pyspark parquet

我正在加载高维镶木地板文件,但只需要几列。我目前的代码如下:

dat = sqc.parquetFile(path) \
          .filter(lambda r: len(r.a)>0) \
          .map(lambda r: (r.a, r.b, r.c))

我发生的事情的心理模型是它在所有数据中加载,然后丢弃我不想要的列。我显然更喜欢它甚至不读这些专栏,以及我对镶木地板的理解,这似乎是可能的。

所以有两个问题:

  1. 我的心理模型错了吗?或者,spark编译器是否足够智能,只能读取上面示例中的a,b和c列?
  2. 如何强制sqc.parquetFile()更有效地读取数据?

3 个答案:

答案 0 :(得分:4)

您应该使用Spark DataFrame API:https://spark.apache.org/docs/1.3.0/sql-programming-guide.html#dataframe-operations

这样的东西
dat.select("a", "b", "c").filter(lambda r: len(r.a)>0)

或者您可以使用Spark SQL:

dat.regiserTempTable("dat")
sqc.sql("select a, b, c from dat where length(a) > 0")

答案 1 :(得分:0)

Spark总是以懒惰的方式做事,使用原生的scala功能。 scala代码已经编译好了,它使运行时变得聪明,我的意思是懒惰,决定。对于镶木地板,它应该只读取代码引用的必要数据。当然,这取决于特定镶木地板文件的结构。关键是它将利用柱状格式。我对Python知之甚少,但它应该能够做同样的事情。也许检查pyspark Row类是否使用某种懒惰魔法。验证的一种快速方法是进行受控实验,编写另一个引用更多字段的rdd操作,但不输出它们。然后你可以比较两个操作之间的挂钟时间差。根据底层镶木地板文件的一些相关细节,即使是延迟加载,您也可能看不到差异。

答案 2 :(得分:0)

是的,它只会从磁盘中选择字段。

“打开所有数据文件,但只读取包含该列值的每个文件的部分。列值连续存储,最小化处理单个列中的值所需的I / O.” p>

本文档适用于impala,我认为阅读逻辑也适用于spark http://www.cloudera.com/documentation/archive/impala/2-x/2-1-x/topics/impala_parquet.html#parquet_data_files_unique_1