Spark Dataframes中的分区和群集

时间:2018-02-01 09:47:05

标签: apache-spark apache-spark-sql

我们是否可以按列进行分区,然后通过Spark中的另一列进行集群?

在我的示例中,我在一个包含数百万行的表中有一个month列和一个cust_id列。我可以说当我将DataFrame保存到配置单元表时,将基于月份和集群的表分区为cust_id到50个文件中吗?

忽略cust_id的群集,这里有三种不同的选项

df.write.partitionBy("month").saveAsTable("tbl")
df.repartition(100).write.partitionBy("month").saveAsTable("tbl")
df.repartition("month").write.saveAsTable("tbl")

第一种情况和最后一种情况类似于Spark所做的但我认为它只是在Hive中编写数据(文件夹而不是每个月的文件)。

在第二个选项中,重新分区被partitionBy撤消了吗?

我怎样才能至少避免这种情况?

甚至可以通过在Spark中指定多个存储桶来说明高基数列的重新分区吗?

2 个答案:

答案 0 :(得分:4)

  

我们是否可以按列进行分区,然后通过Spark中的另一列进行集群?

这是可能的,但repartition不会帮助你。

df.write
  .partitionBy("month")
  .clusterBy(50, "id")
  .saveAsTable("tbl")

相当于:

CREATE TABLE users_bucketed_and_partitioned(
 month T,
 id U
) USING parquet 
PARTITIONED BY (month)
CLUSTERED BY(id) INTO 50 BUCKETS;

请记住,它不是Hive兼容的,并且似乎有意想不到的性能影响。

答案 1 :(得分:0)

只是为了让其他不想修补或编写SQL插入语句的人知道,但在数据框架上使用repartition然后partitionBy实际上是按照我的意愿而不是我的方式工作期待它。

意思是,它首先按键分区,然后重新分配到数字。

示例:

df.repartition(100).write.partitionBy("month").saveAsTable("tbl")

在每个分区内生成100个大小相等的文件,其中在hive的结果表中为每个不同的月份值创建了一个文件夹(分区)。