Spark总结之RDD(四)

Spark总结之RDD(四)1. 背景Spark针对RDD的整体设计思想很多地方和MapReduce相似,但又做了很多优化.Spark整体API设计针对分布式数据处理做了很多优化,并且做了更高层级的抽象,API使用更加简单便捷.例如RDD\DataSet\DataFrame\DStream等本文主要关于RDD的介绍,RDD类型较多,大的分类是Transformation和Action类型,但具体的RDD中又可以进一步细分为基础的RDD和在基础RDD之上的高级RDD(内部调用基础RDD以及各种操作)
摘要由CSDN通过智能技术生成

Spark总结之RDD(四)

1. 背景

  1. Spark针对RDD的整体设计思想很多地方和MapReduce相似,但又做了很多优化.
  2. Spark整体API设计针对分布式数据处理做了很多优化,并且做了更高层级的抽象,API使用更加简单便捷.例如RDD\DataSet\DataFrame\DStream等
  3. 本文主要关于RDD的介绍,RDD类型较多,大的分类是Transformation和Action类型,但具体的RDD中又可以进一步细分为基础的RDD和在基础RDD之上的高级RDD(内部调用基础RDD以及各种操作)
  4. 好的API设计确实是使用便利,而把复杂的内部实现屏蔽起来.并且会对API接口做分层处理,Spark的RDD的API设计就很好体现了这一点,后续源码会有提及.

2. RDD类型

2.1 cogroup

顾名思义,协分组,可以看成是将多个RDD聚合然后根据key进行划分.

    val conf: SparkConf = new SparkConf().setAppName(classOf[CogroupTest].getName)
    conf.setMaster("spark://linux101:7077")

    val sc = new SparkContext(conf)

    // 创建rdd
    val rdd1: RDD[(String, Int)] = sc.makeRDD(List(("tome", 1), ("tome", 2), ("jim", 1), ("tony", 1), ("sanny", 1)), 2)
    val rdd2: RDD[(String, Int)] = sc.makeRDD(List(("tome", 3), ("tome", 1), ("jim", 4), ("tony", 6), ("sanny", 1)), 2)

    // cogroup,将多个rdd联合起来,进行groupByKey的操作。
    // 注意这种方式面对大数据场景,由于没有reduceByKey这种提前局部聚合,效率较低
    // 使用union,然后reduceByKey相对更加高效一些
    val res: RDD[(String, (Iterable[Int], Iterable[Int]))] = rdd1.cogroup(rdd2)

    println(res.collect().toBuffer)

    Thread.sleep(10000000)

运算结果

ArrayBuffer((jim,(CompactBuffer(1),CompactBuffer(4))), (tony,(CompactBuffer(1),CompactBuffer(6))), (sanny,(CompactBuffer(1),CompactBuffer(1))), (tome,(CompactBuffer(1, 2),CompactBuffer(3, 1))))

可以看出,最后的运算结果,是2个RDD中相同的key,value是2者合并起来的结果集合
实际cogroup的源码如下
在这里插入图片描述
注意有多参数的方法重载
在这里插入图片描述
在这里插入图片描述
最终实现这里,可以看到,就是创建了一个CoGroupedRDD,然后这个RDD使用mapValues对内部的数据做处理
处理逻辑就是当前调用cogroup的RDD的values,以及作为参数的RDD的values,其中的values转换为Iterable
返回值最终是RDD[(K, (Iterable[V], Iterable[W]))] ,可以看出最后生成的是对偶数组,key就是2个RDD中的key,value就是2个RDD的value对应数据形成的迭代器,2个迭代器组合而成的对偶数组.
所以整体可以把cogoup看做是把2个或多个RDD相同key的数据抽离出来,放在一起,但结果是以Tuple形式,Tuple中就是不同RDD的values形成的迭代器.
cogroup是产生了shuffle的
http://windows:4040/jobs/job/?id=0 web页面查看信息
在这里插入图片描述
上述可以看出,这里有3个stage, 每个stage是2个分区,并行处理2个task

注意,如果是需要对多个RDD的数据进行处理,可以先union,再局部聚合reduceByKey,这样更加高效.不过数据量少时,使用cogroup性能耗时上不会有太大差异

注意,shuffle的本质和英文名字类似,洗牌.Saprk和MapReduce的shuffle一样,都是把数据打散
数据打散就意味着需要有一个规则将数据划分到不同的区域去,一般是分区器来做这个事情.默认一般是hashPartitioner
实际shuffle分为2个阶段,shuffle write,shuffle read.也就是shuffle前期,数据从内存溢出写到磁盘,然后下游需要拉取这些写道磁盘的数据
shuffle和是否网络传输无关因为上下游有可能在同一个计算机节点上,直接本地通信即可.
shuffle会产生对应的map task

2.2 intersection

顾名思义,就是求RDD之间的交集,隐含着的条件就是2个RDD的数据类型需要一致.(是指RDD产生出来的数据类型需要一致)

    val conf: SparkConf = new SparkConf()
      .setAppName("IntersectionTest")
      .setMaster("local[*]")

    val sc = new SparkContext(conf)

    // 交集
    val rdd1: RDD[Int] = sc.makeRDD(List(2, 3, 4, 5), 2)
    val rdd2: RDD[Int] = sc.makeRDD(List( 4, 5, 6, 7), 2)

    // 就跟集合操作一样,交集就是求出2个集合中共同拥有的元素
    // 所以隐含着一个条件,数据类型需要一样,因为需要2者之间可以对比和判断
    val res: RDD[Int] = rdd1.intersection(rdd2
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值