Learning Spark 笔记(六) -- 指定分区信息改善join()等的操作

原创 2016年08月30日 08:40:35

9 . 默认情况下,join()操作会对两个RDD的主键做哈希以分区,通过网络将主键相同的元素发送到同一台机器上,然后根据相同的主键再进行连接。例子如下:

val sc = new SparkContext()
val userData = sc.sequenceFile[UserID,LinkInfo]("hdfs://...").persist
def processNewLogs(logFileName:String){
    val events = sc.sequenceFile[UserID, LinkInfo](logFileName)
    //RDD of (UserID,(UserInfo,LinkInfo)) pairs
    val joined = usersData.join(events)
    val offTopicVisits = joined.filter {
        // Expand the tuple into its components
        case (userId, (userInfo, linkInfo)) => 
            !userInfo.topics.contains(linkInfo.topic)
    }.count()
    println("Number of visits to non-subscribed opics: " + offTopicVisits)
}

这样的弊端是,两个RDD都会进行shuffle,资源和时间的消耗比较严重。如下图所示:
这里写图片描述
如果userData是一个大数据量、events是一个小数据量的话,每一次join()操作就会进行一次shuffle,这样的弊端体现的会更明显。为解决这个问题,我们可以利用partionBy()来指定分区信息。代码修改如下:

...
val userData = sc.sequenceFile[UserID,LinkInfo]("hdfs://...")
//指定分区信息为100个哈希分区
.partionBy(new HashPartiotioner(100))
//持久化操作,没有持久化等于白做指定分区信息的操作
.persist
...

在之后的join()操作,由于userData含有分区信息,且joined会有和userData一样的分区信息,那么userData就不会有shuffle。比如此处的userData和joined都有HashPartitioner信息,那么userData和joined中的元素只要key相同,就一定会在同一台机器上,所以userData中的数据只会是在本地移动。还一个值得注意的地方是,partionBy()操作也是shuffle,所以在指定分区信息后必须要有持久化操作。如果没有持久化操作,每次执行都会有partitionBy()的shuffle操作,那么就等于啥也没做甚至平白无故又增添shuffle。变化如下图所示:
这里写图片描述

还有另一种改进的方法也可以避免大数据量RDD的shuffle,那就是广播小数据量RDD,弃用join()操作,使用map()操作完成相同功能的操作。

def processNewLogs(logFileName:String){
    val events = sc.sequenceFile[UserID, LinkInfo](logFileName)
    val small = sc.brocast(events)
    //RDD of (UserID,(UserInfo,LinkInfo)) pairs
    val joined = userData.map(x=>{
        val ss = small.value
        ss.map(y=>{
            var tmp:(String,(String,String)) = null
            if(x._1 == y)
                tmp = (x._1,(x._2,y._2))
            tmp
        })
    })
    val offTopicVisits = joined.filter {
        // Expand the tuple into its components
        case (userId, (userInfo, linkInfo)) => 
            !userInfo.topics.contains(linkInfo.topic)
    }.count()
    println("Number of visits to non-subscribed opics: " + offTopicVisits)
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

Spark基础随笔:分区小结

RDD分区的一个分区原则:尽可能是得分区的个数等于集群核心数目 下面我们仅讨论Spark默认的分区个数,这里分别就parallelize和textFile具体分析其默认的分区数 无论是本地模式、Sta...
  • jiangpeng59
  • jiangpeng59
  • 2016年10月08日 14:48
  • 8334

spark的优化-控制数据分区和分布

数据分区: 在分布式集群里,网络通信的代价很大,减少网络传输可以极大提升性能。 mapreduce框架的性能开支主要在io和网络传输,io因为要大量读写文件,它是不可避免的,但是网络传输是可以避免...
  • zengxiaosen
  • zengxiaosen
  • 2016年09月23日 12:30
  • 4904

[Spark--基础]--spark自定义分区及使用方法

Spark中分区器直接决定了RDD中分区的个数、RDD中每条数据经过Shuffle过程属于哪个分区和Reduce的个数 注意: (1)只有Key-Value类型的RDD才有分区的,非Key-Val...
  • high2011
  • high2011
  • 2017年03月30日 19:05
  • 4309

Spark自定义分区(Partitioner)

转自:http://www.iteblog.com/archives/1368 我们都知道Spark内部提供了HashPartitioner和RangePartitioner两种分区策略,这两种...
  • xiao_jun_0820
  • xiao_jun_0820
  • 2015年05月22日 10:10
  • 19681

Spark自定义RDD重分区

在某些计算场景中,我们可能需要将两个有关联的数据输入的部分数据,也就是说RDD中的部分数据,需要聚合在同一个partition进行匹配计算,这个时候,我们就需要根据实际的业务需求,自定义RDD重分区。...
  • cyony
  • cyony
  • 2017年06月26日 14:45
  • 853

spark-spark-SparkSQL的3种Join实现(转)

转载自:http://blog.csdn.net/asongoficeandfire/article/details/53574034 引言 Join是SQL语句中的常用操作,良好的表结构...
  • hjw199089
  • hjw199089
  • 2017年03月22日 17:43
  • 1425

RDD Join 性能调优

阅读本篇博文时,请先理解RDD的描述及作业调度:[《深入理解Spark 2.1 Core (一):RDD的原理与源码分析 》](http://blog.csdn.net/u011239443/arti...
  • u011239443
  • u011239443
  • 2017年01月12日 17:18
  • 3222

spark自定义分区以及写了一个例子,对文件进行处理

  • 2018年01月12日 15:51
  • 574KB
  • 下载

Spark自定义分区(Partitioner)

我们都知道Spark内部提供了HashPartitioner和RangePartitioner两种分区策略(这两种分区的代码解析可以参见:《Spark分区器HashPartitioner和RangeP...
  • sdujava2011
  • sdujava2011
  • 2017年09月16日 19:33
  • 132

Spark的RDD操作之Join大全!

Spark的RDD操作之Join大全! 一、RDD的Join操作有哪些? (一)Join:Join类似于SQL的inner join操作,返回结果是前面和后面集合中配对成功的,过滤掉关联不上的。...
  • PMP4561705
  • PMP4561705
  • 2016年11月18日 08:42
  • 16282
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Learning Spark 笔记(六) -- 指定分区信息改善join()等的操作
举报原因:
原因补充:

(最多只允许输入30个字)