首页 文章

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

提问于
浏览
8

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

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

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

所以有两个问题:

  • 我的心理模型错了吗?或者,spark编译器是否足够智能,只能读取上面示例中的a,b和c列?

  • 如何强制 sqc.parquetFile() 更有效地读入数据?

3 回答

  • 0

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

  • 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")
    
  • 0

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

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

    这个文档是针对impala的,我认为阅读逻辑也是一样的火花http://www.cloudera.com/documentation/archive/impala/2-x/2-1-x/topics/impala_parquet.html#parquet_data_files_unique_1

相关问题