我们是否可以按列进行分区,然后通过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中指定多个存储桶来说明高基数列的重新分区吗?
答案 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的结果表中为每个不同的月份值创建了一个文件夹(分区)。