- 分区:Partitioning:
- 分区数据通常用于水平分配负载,这具有性能优势,并有助于以逻辑方式组织数据。
- 分区表会更改持久化数据的结构,现在将创建反映此分区结构的子目录。
- 这可以显着提高查询性能,但前提是分区方案反映了常见的过滤 。根据指定列进行分区存储,每个列值一个文件结构。
df.write.partitionedBy(column*) .parquet("")
- 分桶:Bucketing:
- Bucketing是另一种将数据集分解为更易于管理的部分的技术 . 根据提供的列,将整个数据散列到用户定义数量的存储区(文件)中 。
- Bucket和Partition的区别,Bucket的最终目的也是实现分区,但是和Partition的原理不同,当我们根据指定列进行Partition的时候,Spark会根据列的名字对数据进行分区(如果没有指定列名则会根据一个随机信息对数据进行分区)。Bucketing的最大不同在于它使用了指定列的哈希值,这样可以保证具有相同列值的数据被分到相同的分区。
- 怎么用 Bucket,按Bucket保存,目前在使用 bucketBy 的时候,必须和 sortBy,saveAsTable 一起使用,如下。这个操作其实是将数据保存到了文件中(如果不指定path,也会保存到一个临时目录中)。
df.write
.bucketBy(10, "name")
.sortBy("name")
.mode(SaveMode.Overwrite)
.option("path","/path/to")
.saveAsTable("bucketed")
将 columns 相同的数据分到同一文件中来分组数据 . 生成的文件个数由 n 控制。
- 重分区:Repartition:
- 它根据给定的分区表达式将一个新的 DataFrame 均衡地返回到给定数量的内部文件中 。生成的DataFrame是散列分区的 。coalesce()方法的参数shuffle默认设置为false,repartition()方法就是coalesce()方法shuffle为true的情况。
1、coalesce()方法源码
def coalesce(numPartitions: Int, shuffle: Boolean = false)(implicit ord: Ordering[T] = null)
: RDD[T] = withScope {
if (shuffle) {
}
else {
}
}
返回一个经过简化到numPartitions个分区的新RDD。这会产生一个窄依赖,例如:你将1000个分区转换成100个分区,这个过程不会发生shuffle,相反如果10个分区转换成100个分区将会发生shuffle。如果想要减少分区数,考虑使用coalesce,这样可以避免执行shuffle。
2、repartition()方法源码
def repartition(numPartitions: Int)(implicit ord: Ordering[T] = null): RDD[T] = withScope {
coalesce(numPartitions, shuffle = true)
}
返回一个恰好有numPartitions个分区的RDD,可以增加或者减少此RDD的并行度。内部使用shuffle重新分布数据。
根据columns内容重新分配partition。请注意,没有数据持久存储到存储,这只是基于类似 bucketBy 的约束的数据内部 Balance。