【问题标题】:Spark Parquet Partitioning: How to choose a keySpark Parquet 分区:如何选择密钥
【发布时间】:2018-09-17 05:15:21
【问题描述】:

我发现默认情况下,Spark 似乎会编写许多小的 parquet 文件。我认为如果我使用分区来减少这种情况可能会更好?

但是我该如何选择分区键呢?例如,对于我经常按 ID 查询的用户数据集,我是否按 id 分区?但我在想,在这种情况下,它会为 1 个用户创建 1 个镶木地板文件吗?

如果我经常按 2 个键查询,但只有 1 个或另一个不能同时查询,那么按两个键分区是否有用?例如,假设我通常通过idcountry 进行查询,我是否使用partitionBy('id', 'country')

如果没有特定的模式来查询数据但又想限制文件数量,那么我是否使用repartition

【问题讨论】:

  • partitionBy 的输出与repartition 不同。 partitionBy 帮助您创建类似 hive 的分区表结构。另一方面,repartition 允许您更改数据帧的分区数,使其等于将要写入的文件数。您还可以将列名传递给repartition
  • 如果我将列名传递给重新分区是否意味着 1 为该列中的每个唯一值获取 1 个文件? @philantrovert
  • 那个和spark.sql.shuffle.partitions的值。如果spark.sql.shuffle.partitions 的值大于给定列的不同值,您将得到空分区

标签: apache-spark pyspark parquet


【解决方案1】:

分区为分区字段的每个值创建一个子目录,因此如果您按该字段进行过滤,而不是读取每个文件,它将只读取相应子目录中的文件。

  • 当您的数据太大时,您应该进行分区并且您通常 一次处理数据的一个子集。

  • 您应该按一个您都需要过滤的字段进行分区 经常具有低基数,即:它将创建一个 相对较少的目录,相对较多的目录 每个目录的数据。

例如,您不想按唯一 ID 进行分区。它会创建很多目录,每个目录只有一行;当您需要选择多个 id 时,这是非常低效的。

如果您使用时间序列(例如每日数据转储)、地理(国家、分支机构等)或分类法(对象类型、制造商等),一些典型的分区字段可能是日期。

【讨论】:

  • 我在考虑日期,但如果我的日期列包含时间,它也没有意义吗?或者是否可以说它应该将值的范围划分在一起?
  • 根据第二点,您应该按范围分组。使用时间戳中的日期创建一个字符串字段很简单(使用 YYYYMMDD 格式)。如果您按这个新字段进行分区,那么您每天都会有一个目录。如果您想从时间戳中选择一个范围,请按新日期字段和时间戳进行过滤。如果您仅按原始时间戳进行过滤,它将不会使用分区,而是会在搜索有效时间戳时读取每个目录。
猜你喜欢
  • 2019-03-02
  • 2018-10-04
  • 1970-01-01
  • 2017-12-02
  • 1970-01-01
  • 1970-01-01
  • 2019-02-17
  • 1970-01-01
  • 2019-07-29
相关资源
最近更新 更多