影响到Spark输出RDD分区的操作函数

下面的操作会影响到Spark输出RDD分区(partitioner)的:
  cogroup, groupWith, join, leftOuterJoin, rightOuterJoin, groupByKey, reduceByKey, combineByKey, partitionBy, sort, mapValues (如果父RDD存在partitioner), flatMapValues(如果父RDD存在partitioner), 和 filter (如果父RDD存在partitioner)。其他的transform操作不会影响到输出RDD的partitioner,一般来说是None,也就是没有partitioner。下面举个例子进行说明:

01 scala> val pairs = sc.parallelize(List((11), (22), (33)))
02 pairs: org.apache.spark.rdd.RDD[(Int, Int)] =
03 ParallelCollectionRDD[4] at parallelize at <console>:12
04  
05 scala> val = sc.parallelize(List(2,51,2,7,3))
06 a: org.apache.spark.rdd.RDD[Int] =
07 ParallelCollectionRDD[5] at parallelize at <console>:12
08  
09 scala> val = sc.parallelize(List(2,51,2))
10 a: org.apache.spark.rdd.RDD[Int] =
11 ParallelCollectionRDD[6] at parallelize at <console>:12
12  
13 scala> val = sc.parallelize(List(3,1,4))
14 b: org.apache.spark.rdd.RDD[Int] =
15  ParallelCollectionRDD[7] at parallelize at <console>:12
16  
17 scala> val = a.zip(b)
18 c: org.apache.spark.rdd.RDD[(Int, Int)] =
19 ZippedPartitionsRDD2[8] at zip at <console>:16
20  
21 scala> val result = pairs.join(c)
22 result: org.apache.spark.rdd.RDD[(Int, (Int, Int))] =
23 FlatMappedValuesRDD[11] at join at <console>:20
24  
25 scala> result.partitioner
26 res6: Option[org.apache.spark.Partitioner] = Some(org.apache.spark.HashPartitioner@2)

  大家可以看到输出来的RDD result分区变成了HashPartitioner,因为join中的两个分区都没有设置分区,所以默认用到了HashPartitioner,可以看join的实现:

01 def join[W](other: RDD[(K, W)]): RDD[(K, (V, W))] = {
02     join(other, defaultPartitioner(self, other))
03 }
04  
05 def defaultPartitioner(rdd: RDD[_], others: RDD[_]*): Partitioner = {
06     val bySize = (Seq(rdd) ++ others).sortBy(_.partitions.size).reverse
07     for (r <- bySize if r.partitioner.isDefined) {
08       return r.partitioner.get
09     }
10     if (rdd.context.conf.contains("spark.default.parallelism")) {
11       new HashPartitioner(rdd.context.defaultParallelism)
12     else {
13       new HashPartitioner(bySize.head.partitions.size)
14     }
15 }

  defaultPartitioner函数就确定了结果RDD的分区。从上面的实现可以看到,
  1、join的两个RDD如果都没有partitioner,那么join结果RDD将使用HashPartitioner;
  2、如果两个RDD中其中有一个有partitioner,那么join结果RDD将使用那个父RDD的partitioner;
  3、如果两个RDD都有partitioner,那么join结果RDD就使用调用join的那个RDD的partitioner。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值