对于Spark中groupByKey的深入理解

 XML Code 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package com.lyzx.day16

import org.apache.spark.{SparkContext, SparkConf}


class T1 {

   /**
   *  对于 groupByKey 的深入理解
   *
   * groupByKey是一个shuffle类的算子
   * 即它会引起洗牌操作有可能引起提交任务数量的改变
   * 是否会改变partition的数量(即提交任务的数量)
   * 取决于其参数是否和上一个RDD的partition一样
   *
   * 首先看算子的参数N有没有传
   * 再看默认的并行度M
   * 最后看上一个RDD的Partition数量X
   * 优先级:N >M >X
   * /
  def f1(sc:SparkContext): Unit ={
    val arr = List(1,2,3,4,5,6,7,8,9,9,8,7,6,5,4,3,2,1)

     //这个方法没有提供第二个参数,默认把所有的数据放入到一个partition里面
    val rdd = sc.parallelize(arr)

     //从打印的日志可以看出所有的数据都在一个partition里面
    rdd.mapPartitionsWithIndex((index,itr)= >{
      print( "1:::currentIndex:"+index+ "  ")
      while(itr.hasNext){
        print(itr.next()+ "-")
      }
      println()
      for(value  <- itr) yield value
    }).foreach(println)

    /*
    把一个Partition里面的数据分散到3个partition里面

    从新分区把一个partition里面的数据放到3个分区里面,这是一个shuffle操作
    在每一个partition内部在分区 比如要把RDD1中的3个partition变为RDD2中的5个partition
    具体的做法是把RDD1中的每一个partition分为5份(每一份暂时称为碎片)
      RDD1中的partition
      partition1  [p1_0 p1_1 p1_2 p1_3 p1_4]
      partition2  [p2_0 p2_1 p2_2 p2_3 p2_4]
      partition3  [p3_0 p3_1 p3_2 p3_3 p3_4]

      把RDD1中的partition的
"碎片" 的编号为0的放入一个新的partition
        编号为1的放入一个新的partition
        以此类推
      RDD2中的partition
      partition1  [p1_0 p2_0 p3_0]
      partition2  [p1_1 p2_1 p3_1]
      partition3  [p1_2 p2_2 p3_2]
      partition4  [p1_3 p2_3 p3_3]
      partition5  [p1_4 p2_4 p3_4]
     */
    val rdd3 
=  rdd.repartition( 3 )
    rdd3.mapPartitionsWithIndex((index,itr)
= >{
      print( "3:::currentIndex:"+index+ "  ")
      while(itr.hasNext){
        print(itr.next()+ "=")
      }
      println()
      for(value  <- itr) yield value
    }).foreach(println)

    println(
"==========================" )
    //[(
1 , 1 ),( 2 , 2 ),( 3 , 3 ),( 4 , 4 ),( 5 , 5 ),( 6 , 6 ),( 7 , 7 ),( 8 , 8 ),( 9 , 9 ),( 9 , 9 )( 8 , 8 ),( 7 , 7 ),( 6 , 6 ),( 5 , 5 ),( 4 , 4 ),( 3 , 3 ),( 2 , 2 ),( 1 , 1 )]
    val mapRdd 
=  rdd3.map(item= >(item,item))

     //[(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9),(9,9)(8,8),(7,7),(6,6),(5,5),(4,4),(3,3),(2,2),(1,1)]
    val groupRdd = mapRdd.groupByKey(5)
    groupRdd.foreach(item= >{
      val key = item._1
      val values = item._2
      print( ">>>>::"+key+ "---"+values)
      values.foreach(item= >{
        print( " <<"+item)
      })
      println()
    })

  }
}

object T1{
  def main(args: Array[String]) {
    val conf = new SparkConf().setAppName( "myTest").setMaster( "local")
    val sc = new SparkContext(conf)

    val t = new T1
    t.f1(sc)
    sc.stop()
  }
}

你可能感兴趣的:(对于Spark中groupByKey的深入理解)