Learning Spark 笔记(七) -- 受益于分区的操作

原创 2016年08月30日 17:24:12

10 . 单元操作是怎样受益的?以reduceByKey为例子,reduceByKey是在本地归约后再发送到一个主机上再进行归约。如果父RDD是有分区信息的,那么就可能只会在本地归约了,而不会再跨网络发送到其它主机上。

二元操作是怎样受益于分区的?比如join(),至少会有一个RDD不会被shuffle。如果两个RDD有同样的partitioner,且被缓存在相同的机器上,则不会shuffle产生,比如

val b = a.mapValues(x=>x*x)
a.join(b)

因为mapValues()操作不会改变主键且不是shuffle操作,所以a和b的分区信息是一样的且在同一台机器上,二元操作join()不会有shuffle产生。

受分区信息影响的操作有

//一定会输出有Partitioner子RDD的操作
cogroup(),groupWith(), join(), leftOuterJoin(), rightOuterJoin(), groupByKey(), sort(), reduceByKey(),combineByKey(), partitionBy(),  
//如果有父RDD指定了Partitioner,则一定会输出有Partitioner的子RDD的操作
mapValues(), flatMapValues(), filter()

除了上面的这些操作,其它的操作都不会产生Partitioner。

最后三个操作
那么子RDD是怎样确定Partitioner和分区的呢?下面是Spark2.0.0的Partition.defaultPartitioner的源码,源码中定义了怎样确定子RDD的partitioner和分区数。

/**
   * Choose a partitioner to use for a cogroup-like operation between a number of RDDs.
   *
   * If any of the RDDs already has a partitioner, choose that one.
   *
   * Otherwise, we use a default HashPartitioner. For the number of partitions, if spark.default.parallelism is set, then we'll use the value from SparkContext defaultParallelism, otherwise we'll use the max number of upstream partitions.
   *
   * Unless spark.default.parallelism is set, the number of partitions will be the same as the number of partitions in the largest upstream RDD, as this should be least likely to cause out-of-memory errors.
   *
   * We use two method parameters (rdd, others) to enforce callers passing at least 1 RDD.
   */
  def defaultPartitioner(rdd: RDD[_], others: RDD[_]*): Partitioner = {
    val bySize = (Seq(rdd) ++ others).sortBy(_.partitions.length).reverse
    for (r <- bySize if r.partitioner.isDefined && r.partitioner.get.numPartitions > 0) {
      return r.partitioner.get
    }
    if (rdd.context.conf.contains("spark.default.parallelism")) {
      new HashPartitioner(rdd.context.defaultParallelism)
    } else {
      new HashPartitioner(bySize.head.partitions.length)
    }
  }

可以看到:
1. 父RDD中只有一个指定了Partitioner,则子RDD继承这个partitioner;
2. 父RDD中有若干个指定了Partitioner,则子RDD继承的是分区数最多的那个父RDD的Partitioner;
3. 如果父RDD中没有一个指定了Partitioner,则子RDD默认是HashPartitioner;
4. 在并行度没有指定的情况下,子RDD的分区数是和最大分区数的父RDD是一致的,如果指定了就优先使用指定的并行度。

利用partitionBy()操作优化程序的例子,PageRank:

// Assume that our neighbor list was saved as a Spark objectFile
val links = sc.objectFile[(String, Seq[String])]("links")
                //指定分区为哈希
                .partitionBy(new HashPartitioner(100))
                //持久化,默认为Storagelevel.MEMORY_ONLY                               
                .persist()                                                           
// Initialize each page's rank to 1.0; since we use mapValues, the resulting RDD will have the same partitioner as links
//mapValues不会改变分区信息
var ranks = links.mapValues(v => 1.0)                                             
// Run 10 iterations of PageRank
for (i <- 0 until 10) {
    //flatMap会改变分区信息,但却没有改变分区数100,所以contributions并没有持有links的RDD的分区信息
    val contributions = links.join(ranks).flatMap {                               
        case (pageId, (links, rank)) =>
            links.map(dest => (dest, rank / links.size))
    }
//  reduceByKey会产生默认的HashPartitioner分区,并且继承了之前的分区数,mapValues没有改变分区信息
ranks = contributions.reduceByKey((x, y) => x + y).mapValues(v => 0.15 + 0.85*v)
}
// Write out the final ranks
ranks.saveAsTextFile("ranks")

要最大化潜在的分区相关的优化,应该使用mapValues或者flatMapValues(),无论什么时候都不要改变元素的主键。

版权声明:本文为博主原创文章,未经博主允许不得转载。

Spark—聚合操作—combineByKey

聚合操作——combineByKey当数据集一键值对形式组织的时候,聚合具有相同键的元素进行一些统计是很常见的操作。对于Pair RDD常见的聚合操作如:reduceByKey,foldByKey,g...
  • sicofield
  • sicofield
  • 2016年03月22日 18:30
  • 8114

Spark性能调试之小分区合并

Spark性能调试是使用Spark的用户在进行大数据处理的时候必须面对的问题,性能调优的方法有很多,这里首先介绍一种常见的调优问题-小分区合并问题。小分区合并问题介绍在使用Spark进行数据处理的过程...
  • do_yourself_go_on
  • do_yourself_go_on
  • 2017年07月04日 13:28
  • 130

Spark数据分区

Spark程序可以通过分区来减少网络通信开销。分区并非对于所有场景都是有好处的:比如, 如果给定RDD只被扫描一遍,那么完全没有必要做分区, 只有当数据多次在诸如连接这种基于键的操作时,分区才会有帮助...
  • wusuopuBUPT
  • wusuopuBUPT
  • 2016年11月20日 00:55
  • 889

分区的操作类型

一、分区的定义: 分区表是将大表的数据分成许多小的子集,而这些小的子集便称为分区。 二、分区的优点:        1 、增强可用性:如果表的一个分区由于系统故障而不能使用,表的其余好的分区仍然可以使...
  • siyanyanyanyai
  • siyanyanyanyai
  • 2014年03月22日 14:05
  • 1286

Coursera Machine Learning 课程笔记之第一周:Introduction

有监督学习(Supervised Learning):我们有一个数据集,如果我们的每一个单一的数据根据它的特征向量我们要去判断它的标签(算法的输出值),那么就是有监督学习。 有监督学习,分为两个大...
  • jibancanyang
  • jibancanyang
  • 2015年12月23日 11:50
  • 493

Learning Spark 中文版,第三章到第八章整理完毕,PDF可下载

下载地址:Learning Spark中文版3-8章带目录文字版 http://download.csdn.net/detail/coding_hello/9161...
  • coding_hello
  • coding_hello
  • 2015年10月07日 23:00
  • 4689

Stanford Machine Learning 公开课笔记(1) Linear Regression

【NOTES】 regression: to predict the continues valued output. classification: to predi...
  • feliciafay
  • feliciafay
  • 2014年04月05日 15:12
  • 4841

Deep learning笔记(更新中)

Goodfellow和Bengio的Deep Learning一书的笔记
  • kaka19880812
  • kaka19880812
  • 2017年02月26日 22:29
  • 499

Coursera Machine Learning 学习笔记(一)

Coursera Machine Learning 学习笔记(一)
  • u013538664
  • u013538664
  • 2015年02月28日 00:46
  • 1969

笔记 | 吴恩达Coursera Deep Learning学习笔记

向AI转型的程序员都关注了这个号☝☝☝作者:Lisa Song微软总部云智能高级数据科学家,现居西雅图。具有多年机器学习和深度学习的应用经验,熟悉各种业务场景下机器学习和人工智能产品的需求分析、架构设...
  • dQCFKyQDXYm3F8rB0
  • dQCFKyQDXYm3F8rB0
  • 2017年09月27日 00:00
  • 1338
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Learning Spark 笔记(七) -- 受益于分区的操作
举报原因:
原因补充:

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