1.partitionBy
1)函数签名
def partitionBy(partitioner: Partitioner): RDD[(K, V)]
2)函数说明
将数据按照指定 Partitioner 重新进行分区。Spark 默认的分区器是 HashPartitioner
注意:要将 rdd 转换为 Key-Value 元组类型,才能调用 partitionBy
import org.apache.spark.{
HashPartitioner, SparkConf, SparkContext}
object TestRDD {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setMaster("local[*]").setAppName("Operator")
val sc = new SparkContext(sparkConf)
val rdd = sc.makeRDD(List(1,2,3,4))
rdd.map((_, 1))
.partitionBy(new HashPartitioner(2))
.saveAsTextFile("output")
sc.stop
}
}
结果为 output 目录下生成两个文件 part-00000 和 part-00001,内容分别为
(2,1),(4,1)和(1,1),(3,1)
3)HashPartitioner
底层核心源码如下:
4)如果重分区的分区器和当前 RDD 的分区器相同?
分区前,会首先判断 重分区的分区器和当前 RDD 分区器是否相同(类型,分区数量),如果相同,不会重新分区
5)Spark 还有其他分区器
HashPartitioner,RangePartitioner,PythonPartitioner
6)可以自定义分区器进行数据分区
2.reduceByKey
1)函数签名
def reduceByKey(func: (V, V) => V): RDD[(K, V)]
def reduceByKey(func: (V, V) => V, numPartitions: Int): RDD[(K, V)]
2)函数说明
可以将数据按照相同的 Key 对 Value 进行聚合
import org.apache.spark.{
SparkConf, SparkContext}
object TestRDD {
def main(args: Array[String]): Unit = {
val sparkConf = new SparkConf().setMaster("local[*]").setAppName("Operator")
val sc = new SparkContext(sparkConf)
val rdd = sc.makeRDD(List(
("a", 1), ("a", 2), ("a", 3), ("b", 4)
))
rdd.reduceByKey(_ + _)
.collect.foreach(println)
sc.stop
}
}
输出结果为(a,6)(b,4)
说明:reduceByKey 中如果 Key 的数据只有一个,是不会参与运算的
3.groupByKey
1)函数签名
def groupByKey(): RDD[(K, Iterable[V])]
def groupByKey(numPartitions: Int): RDD[(K, Iterable[V])]
def groupByKey(partitioner: Partitioner): RDD[(K, Iterable[V])