分区两要素
分区有两个要素:1.分区个数 2.分区规则
在RDD中,我们一般只指定了分区个数,并没有写分区规则,分区规则就由分区器决定。
Spark自带分区器
(1) Spark目前支持Hash分区和Range分区,和用户自定义分区。Hash分区为当前的默认分区。
(2) Range分区器要求必须能够排序,range能解决数据倾斜
分区器特点
- 分区器直接决定了RDD中分区的个数、RDD中每条数据经过Shuffle后进入哪个分区,进而决定了Reduce的个数,也就是输出文件的个数。
- 只有Key-Value类型的RDD才有分区器,非Key-Value类型的RDD分区的值是None
- 每个RDD的分区ID范围:0 ~ (numPartitions - 1),决定这个值是属于那个分区的。
自定义分区器
1.分区器怎么写?
可以参考HashPartitioner怎么写的,此例子中是固定了分区个数,hashpartitioner是作为构造参数传进来的
2.自定义分区器怎么用
在可以传入分区器的算子中使用,比如partitioneBy
HashPartitioner
分区规则:对于给定的key,计算其hashCode,并除以分区个数取余
class HashPartitioner(partitions: Int) extends Partitioner {
require(partitions >= 0, s"Number of partitions ($partitions) cannot be negative.")
def numPartitions: Int = partitions
def getPartition(key: Any): Int = key match {
case null => 0
case _ => Utils.nonNegativeMod(key.hashCode, numPartitions)
}