RDD常用的算子操作, map和mapPartitions区别, groupByKey和groupBy区别, repartition和coalesce区别, 广播大变量broadcast 09

1. filter

filter 是对RDD中的每个元素都执行一个指定的函数来过滤产生一个新的RDD。 任何原RDD中的元素在新RDD中都有且只有一个元素与之对应。

val rdd = sc.parallelize(List(1,2,3,4,5,6))  
val filterRdd = rdd.filter(_ > 5)
filterRdd.collect() //返回所有大于5的数据的一个Array, Array(6,8,10,12)

2. flatMap

与map类似,区别是原RDD中的元素经map处理后只能生成一个元素,而原RDD中的元素经flatmap处理后可生成多个元素来构建新RDD。 举例:对原RDD中的每个元素x产生y个元素(从1到y,y为元素x的值)

scala> val a = sc.parallelize(1 to 4, 2)
scala> val b = a.flatMap(x => 1 to x)
scala> b.collect
res12: Array[Int] = Array(1, 1, 2, 1, 2, 3, 1, 2, 3, 4)

3. map和mapParitions区别

3.1 map

  • map是对RDD中的每个元素都执行一个指定的函数来产生一个新的RDD.
  • 任何原RDD中的元素在新的RDD中都有且只有一个元素与之对应.
scala> val a = sc.parallelize(1 to 9, 3)
scala> val b = a.map(x => x*2)
scala> a.collect
res10: Array[Int] = Array(1, 2, 3, 4, 5, 6, 7, 8, 9)
scala> b.collect
res11: Array[Int] = Array(2, 4, 6, 8, 10, 12, 14, 16, 18)

上述例子中把原RDD中每个元素都乘以2来产生一个新的RDD。

3.2 mapParitions

  • mapParitions是map的一个变种.map的输入函数是应用于RDD中每个元素.
  • 而mapParitions的输入函数是应用于每个分区,也就是把每个分区中的内容作为整体来处理的.
scala> val a = sc.parallelize(1 to 9, 3)
scala> def myfunc[T](iter: Iterator[T]) : Iterator[(T, T)] = {
  var res = List[(T, T)]() 
  var pre = iter.next 
while (iter.hasNext) {
    val cur = iter.next
    res.::=(pre, cur)
      pre = cur  } 
  res.iterator
}
  • 上述例子中的函数myfunc是把分区中一个元素和它的下一个元素组成一个Tuple。因为分区中最后一个元素没有下一个元素了,所以(3,4)和(6,7)不在结果中。
  • mapPartitions还有些变种,比如mapPartitionsWithContext,它能把处理过程中的一些状态信息传递给用户指定的输入函数。还有mapPartitionsWithIndex,它能把分区的index传递给用户指定的输入函数。

4. 交集intersection, 并集union

  • 都依赖于两个rdd.
val rdd1 = sc.parallelize(List(5,6,4,3))
val rdd2 = sc.parallelize(List(1,2,3,4))
//求并集
val rdd3 = rdd1.union(rdd2)
//求交集
val rdd4 = rdd1.intersection(rdd2)
//去重
rdd3.distinct.collect
rdd4.collect

5. join() 左连接

  • join() rdd两两左连接
  • rdd1.join(rdd2) --> Array(k, (v,w))
  • 以rdd1为基准
val rdd7: RDD[(String, Any)] = sc.parallelize(List(("tom", "aa"),("tom", 1), ("tom", "bb"),("jerry", 3), ("kitty", 2)))
val rdd8 = sc.parallelize(List(("jerry", 2), ("tom", 1), ("shuke", 2)))
//join
 val join: RDD[(String, (Any, Int))] = rdd7.join(rdd8)
 val c7: Array[(String, (Any, Int))] = join.collect()
//结果 ArrayBuffer((tom,(aa,1)), (tom,(1,1)), (tom,(bb,1)), (jerry,(3,2)))

6. cogroup和groupByKey区别

6.1 cogroup()

  • 同一个rdd中, 相同k的value迭代组成迭代器k,(Iterator[v],Iterator[w])
  • 依赖于两个rdd
  • 举例: rdd.cogroup(rdd2)
 val rdd9: RDD[(String, Any)] = sc.parallelize(List(("tom", "aa"),("tom", 1), ("tom", "bb"),("jerry", 3), ("kitty", 2)))
 val rdd10 = sc.parallelize(List(("jerry", 2), ("tom", 1), ("shuke", 2)))
 val cogroup: RDD[(String, (Iterable[Any], Iterable[Int]))] = rdd9.cogroup(rdd10)
    val c9: Array[(String, (Iterable[Any], Iterable[Int]))] = cogroup.collect()
//结果
ArrayBuffer((tom,(CompactBuffer(aa, 1, bb),CompactBuffer(1))), (jerry,(CompactBuffer(3),CompactBuffer(2))), (shuke,(CompactBuffer(),CompactBuffer(2))), (kitty,(CompactBuffer(2),CompactBuffer())))

6.2 groupByKey()

  • 不依赖多个RDD,一个rdd执行起来的算子
  • 求一个集合的相同k合并后的value, shuffle阶段, 得到的value是迭代器 rdd.groupByKey()得到的是 Array(k, Iterator[v])
 val rdd7: RDD[(String, Any)] = sc.parallelize(List(("tom", "aa"),("tom", 1), ("tom", "bb"),("jerry", 3), ("kitty", 2))) 
val key: RDD[(String, Iterable[Any])] = rdd7.groupByKey()
 val c77: Array[(String, Iterable[Any])] = key.collect()
//结果 
ArrayBuffer((tom,CompactBuffer(aa, 1, bb)), (jerry,CompactBuffer(3)), (kitty,CompactBuffer(2)))

7. groupBy()

  • **groupBy()**更加灵活 返回的是 k, Iterator(k,v)
ArrayBuffer((tom,CompactBuffer((tom,aa), (tom,1), (tom,bb))), (jerry,CompactBuffer((jerry,3))), (kitty,CompactBuffer((kitty,2))))

8. reduce

val rdd1 = sc.parallelize(List(1, 2, 3, 4, 5))
//reduce聚合
val rdd2 = rdd1.reduce(_ + _)
rdd2.collect

9. reduceByKey, sortByKey

val rdd1 = sc.parallelize(List(("tom", 1), ("jerry", 3), ("kitty", 2),  ("shuke", 1)))
val rdd2 = sc.parallelize(List(("jerry", 2), ("tom", 3), ("shuke", 2), ("kitty", 5)))
val rdd3 = rdd1.union(rdd2)
//按key进行聚合
val rdd4 = rdd3.reduceByKey(_ + _)
rdd4.collect
//按value的降序排序
val rdd5 = rdd4.map(t => (t._2, t._1)).sortByKey(false).map(t => (t._2, t._1))
rdd5.collect

10. 重点, 分区划分->repartition和coalesce区别

  • reparition可以增加和减少RDD中的分区数
  • coalesce只能减少RDD分区数,增加RDD分区数不会生效.
val rdd1 = sc.parallelize(1 to 10,3)
//利用repartition改变rdd1分区数
//减少分区
rdd1.repartition(2).partitions.size
//增加分区
rdd1.repartition(4).partitions.size
//利用coalesce改变rdd1分区数
//减少分区
rdd1.coalesce(2).partitions.size

11. Spark中广播变量

  • 一个executor有多个task,每个task都会被加载数据,为了减轻内部压力,将公共的数据广播出去
  • 广播的是字典数据(也就是不会频繁改变的数据)
  • 放到每一个executor中一个公共的位置
  • 广播的数据是Action动作后的数据
//广播数据(广播action动作后的数据)
val broadcast: Broadcast[Array[(String, String, String, String)]] = sc.broadcast(collect)
//取数据
val valueArr: Array[(String, String, String, String)] = broadcast.value
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值