RDD操作

写了一个月spark,用了无数RDD操作,总结一下~

 

RDD Transform

  • map(func) : 数据集中的每个元素经过用户自定义的函数转换形成一个新的RDD
    val rdd = sc.parallelize(1 to 5)
    val result = rdd.map(x => x to 3)

     输出:

    Range(1, 2, 3)
    Range(2, 3)
    Range(3)
    Range()
    Range()
  • flatmap(func) : 与map类似,但每个元素输入项都可以被映射到0个或多个的输出项,最终将结果”扁平化“后输出
    val rdd = sc.parallelize(1 to 5)
    val result = rdd.flatMap(x => x to 3)

    输出:

    1
    2
    3
    2
    3
    3
  • union(otherDataset) : 将两个RDD中的数据集进行合并,最终返回两个RDD的并集,若RDD中存在相同的元素也不会去重
    val rdd1 = sc.parallelize(1 to 3)
    val rdd2 = sc.parallelize(3 to 5)
    val result = rdd1.union(rdd2)

    输出:

    1
    2
    3
    3
    4
    5
  • intersection(otherDataSet) : 返回两个RDD的交集
    val rdd1 = sc.parallelize(1 to 3)
    val rdd2 = sc.parallelize(3 to 5)
    val result = rdd1.intersection(rdd2)

    输出:

    3                      
  • cogroup(otherDataset, numPartitions) : 对两个RDD(如:(K,V)和(K,W))相同Key的元素先分别做聚合,最后返回(K,Iterator<V>,Iterator<W>)形式的RDD, numPartitions设置分区数,提高作业并行度
    val rdd1 = sc.parallelize(List(("A", 1), ("B", 2), ("A", 2), ("B", 3), ("C", 4)))
    val rdd2 = sc.parallelize(List(("A", "A1"), ("B", "B1"), ("A", "A2"), ("B", "B2")))
    val result = rdd1.cogroup(rdd2)

    输出:

    (A,(CompactBuffer(1, 2),CompactBuffer(A1, A2)))
    (B,(CompactBuffer(2, 3),CompactBuffer(B1, B2)))
    (C,(CompactBuffer(4),CompactBuffer()))

  • join(otherDataset, [numTasks]) : 对两个RDD先进行cogroup操作形成新的RDD,再对每个Key下的元素进行笛卡尔积,numPartitions设置分区数,提高作业并行度
    val rdd1 = sc.parallelize(List(("A", 1), ("B", 2), ("A", 2), ("B", 3), ("C", 4)))
    val rdd2 = sc.parallelize(List(("A", "A1"), ("B", "B1"), ("A", "A2"), ("B", "B2")))
    val result = rdd1.join(rdd2)

    输出:

    // 注意:没有C,和空集的笛卡儿积为空集
    (A,(1,A1))
    (A,(1,A2))
    (A,(2,A1))
    (A,(2,A2))
    (B,(2,B1))
    (B,(2,B2))
    (B,(3,B1))
    (B,(3,B2))
  • distinct([numTasks]) : 对RDD中的元素进行去重
    val rdd1 = sc.parallelize(1 to 3)
    val rdd2 = sc.parallelize(3 to 5)
    val result = rdd1.union(rdd2).distinct()

    输出:

    1
    2
    3
    4
    5
  • reduceByKey(func, [numTasks]) : 按Key进行分组,使用给定的func函数聚合value值, numPartitions设置分区数,提高作业并行度
    val rdd1 = sc.parallelize(List(("A", 1), ("B", 2), ("A", 2), ("B", 3), ("C", 4)))
    val result = rdd1.reduceByKey(_+_)

    输出:

    (A,3)
    (B,5)
    (C,4)
  • groupByKey(numPartitions) : 按Key进行分组,返回[K,Iterable[V]],numPartitions设置分区数,提高作业并行度
    val rdd1 = sc.parallelize(List(("A", 1), ("B", 2), ("A", 2), ("B", 3), ("C", 4)))
    val result = rdd1.groupByKey()

    输出:

    (A,CompactBuffer(1, 2))
    (B,CompactBuffer(2, 3))
    (C,CompactBuffer(4))
  • sortByKey(accending, numPartitions) : 返回以Key排序的(K,V)键值对组成的RDD,accending为true时表示升序,为false时表示降序,numPartitions设置分区数,提高作业并行度 (很明显得功能,不举例了
  • combineByKey(createCombiner, mergeValue, mergeCombiners, partitioner, mapSideCombine)
    createCombiner : 在第一次遇到Key时创建组合器函数,将RDD数据集中的V类型值转换C类型值(V => C)
    mergeValue : 合并值函数,再次遇到相同的Key时,将createCombiner道理的C类型值与这次传入的V类型值合并成一个C类型值(C,V)=>C
    mergeCombiners : 合并组合器函数,将C类型值两两合并成一个C类型值
    partitioner : 使用已有的或自定义的分区函数,默认是HashPartitioner
    mapSideCombine : 是否在map端进行Combine操作,默认为true
    val people = List(("male", "Mobin"), ("male", "Kpop"), ("female", "Lucy"), ("male", "Lufei"), ("female", "Amy"))
    val rdd = sc.parallelize(people)
    val result = rdd.combineByKey(
      (x: String) => (List(x), 1),
      (peo: (List[String], Int), x : String) => (x :: peo._1, peo._2 + 1),
      (sex1: (List[String], Int), sex2: (List[String], Int)) => (sex1._1 ::: sex2._1, sex1._2 + sex2._2)
    )

    输出:

    (male,(List(Mobin, Kpop, Lufei),3))
    (female,(List(Lucy, Amy),2))

    过程解析:

    Partition1:
    K="male"  -->  ("male","Mobin")  --> createCombiner("Mobin") =>  peo1 = (  List("Mobin") , 1 )
    K="male"  -->  ("male","Kpop")  --> mergeValue(peo1,"Kpop") =>  peo2 = (  "Kpop"  ::  peo1_1 , 1 + 1 )    //Key相同调用mergeValue函数对值进行合并
    K="female"  -->  ("female","Lucy")  --> createCombiner("Lucy") =>  peo3 = (  List("Lucy") , 1 )
     
    Partition2:
    K="male"  -->  ("male","Lufei")  --> createCombiner("Lufei") =>  peo4 = (  List("Lufei") , 1 )
    K="female"  -->  ("female","Amy")  --> createCombiner("Amy") =>  peo5 = (  List("Amy") , 1 )
     
    Merger Partition:
    K="male" --> mergeCombiners(peo2,peo4) => (List(Lufei,Kpop,Mobin))
    K="female" --> mergeCombiners(peo3,peo5) => (List(Amy,Lucy))

RDD Action

Action操作都很简单,就不举例了

  • reduce(func) : 通过函数func先聚集各分区的数据集,再聚集分区之间的数据,func接收两个参数,返回一个新值,新值再做为参数继续传递给函数func,直到最后一个元素
  • collect() : 以数据的形式返回数据集中的所有元素给Driver程序,为防止Driver程序内存溢出,一般要控制返回的数据集大小
  • count() : 返回数据集元素个数
  • first() : 返回数据集的第一个元素
  • saveAsTextFile(path) : 将最终的结果数据保存到指定的目录中

 

posted @ 2018-09-20 15:52  yZi  阅读(183)  评论(0编辑  收藏  举报