文章目录
RDD 分区器
Spark 目前支持 Hash 分区和 Range 分区,和用户自定义分区。Hash 分区为当前的默认分区。分区器直接决定了RDD中分区的个数,RDD中每条数据经过 Shuffle 后进入哪个分区,进而决定了Reduce 的个数。
- 只有Key-Value 类型的 RDD 才有分区器,非Key-Value 类型的RDD分区的值是None。
- 每个RDD的分区ID范围:0~(numPartitions-1),决定这个值是属于哪个分区的。
RDD 自定义分区器:
首先自己写一个自定义分区器类,继承Partitioner
类,这是一个抽象类,要实现里面的方法,里面有一个方法,第一个方法是分区的个数。第二个方法是 根据数值的key值返回数据的分区索引(从0开始),直接对key
进行if判断,如果key=="nba" 那么就返回一个0
,也就是0号分区,如果key=="cba"那么返回一个1
,也就是一号分区。这样根据key来进行分区一下就分出来了,三个分区。
注意:这个也要是key-value类型的,因为是根据key来分的。
package com.atguigu.bigdata.spark.core.wc.Dep
import org.apache.spark.rdd.RDD
import org.apache.spark.{Partitioner, SparkConf, SparkContext}
//RDD 分区器: 之前说了Spark有hash分区器,range分区器,还有python分区器
//但是没有细说,现在来详细说说
class Spark03_RDD_Partitions {
}
object Spark03_RDD_Partitions{
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[*]").setAppName("RDD")
val context = new SparkContext(conf)
val rdd = context.makeRDD(List(
("nba","xxxx"), //比如我先把nba 放在0号分区,cba放1号分区,wnba放2哈分区
("cba","xxxx"), //但是默认分区的话,他不会这么放
("wnba","xxxx"),
("nba","xxxx")
),3)
val partionRDD: RDD[(String, String)] = rdd.partitionBy(new MyPartitioner)
partionRDD.saveAsTextFile("datas/there.txt")
context.stop()
}
/*
* 自定义分区器
* 1、继承 Partitioner 类
* 2、重写方法
* 第一个重写的方法是分区的数量,第二个方法是返回数据的分区索引
* */
class MyPartitioner extends Partitioner{ //继承Partitioner这个类,是个抽象类我们的实现
//分区数量
override def numPartitions: Int = 3
//根据数值的key值返回数据的分区索引(从0开始)
override def getPartition(key: Any): Int = {
if(key=="nba"){ //如果key是nba那么返回0,也就是0号分区
0
}else if(key == "cba"){
1
}else{
2
}
}
}
}