Spark自定义分区(Partitioner)

转载 2016年05月31日 14:26:06

 我们都知道Spark内部提供了HashPartitionerRangePartitioner两种分区策略(这两种分区的代码解析可以参见:《Spark分区器HashPartitioner和RangePartitioner代码详解》),这两种分区策略在很多情况下都适合我们的场景。但是有些情况下,Spark内部不能符合咱们的需求,这时候我们就可以自定义分区策略。为此,Spark提供了相应的接口,我们只需要扩展Partitioner抽象类,然后实现里面的三个方法:

01 package org.apache.spark
02  
03 /**
04  * An object that defines how the elements in a key-value pair RDD are partitioned by key.
05  * Maps each key to a partition ID, from 0 to `numPartitions - 1`.
06  */
07 abstract class Partitioner extends Serializable {
08   def numPartitions: Int
09   def getPartition(key: Any): Int
10 }

  def numPartitions: Int:这个方法需要返回你想要创建分区的个数;
  def getPartition(key: Any): Int:这个函数需要对输入的key做计算,然后返回该key的分区ID,范围一定是0到numPartitions-1
  equals():这个是Java标准的判断相等的函数,之所以要求用户实现这个函数是因为Spark内部会比较两个RDD的分区是否一样。

  假如我们想把来自同一个域名的URL放到一台节点上,比如:http://www.iteblog.comhttp://www.iteblog.com/archives/1368,如果你使用HashPartitioner,这两个URL的Hash值可能不一样,这就使得这两个URL被放到不同的节点上。所以这种情况下我们就需要自定义我们的分区策略,可以如下实现:

01 package com.iteblog.utils
02  
03 import org.apache.spark.Partitioner
04  
05 /**
06  * User: 过往记忆
07  * Date: 2015-05-21
08  * Time: 下午23:34
09  * bolg: http://www.iteblog.com
10  * 本文地址:http://www.iteblog.com/archives/1368
11  * 过往记忆博客,专注于hadoop、hive、spark、shark、flume的技术博客,大量的干货
12  * 过往记忆博客微信公共帐号:iteblog_hadoop
13  */
14  
15 class IteblogPartitioner(numParts: Int) extends Partitioner {
16   override def numPartitions: Int = numParts
17  
18   override def getPartition(key: Any): Int = {
19     val domain = new java.net.URL(key.toString).getHost()
20     val code = (domain.hashCode % numPartitions)
21     if (code < 0) {
22       code + numPartitions
23     else {
24       code
25     }
26   }
27  
28   override def equals(other: Any): Boolean = other match {
29     case iteblog: IteblogPartitioner =>
30       iteblog.numPartitions == numPartitions
31     case _ =>
32       false
33   }
34  
35   override def hashCode: Int = numPartitions
36 }

因为hashCode值可能为负数,所以我们需要对他进行处理。然后我们就可以在partitionBy()方法里面使用我们的分区:

1 iteblog.partitionBy(new IteblogPartitioner(20))

  类似的,在Java中定义自己的分区策略和Scala类似,只需要继承org.apache.spark.Partitioner,并实现其中的方法即可。

  在Python中,你不需要扩展Partitioner类,我们只需要对iteblog.partitionBy()加上一个额外的hash函数,如下:

1 import urlparse
2  
3 def iteblog_domain(url):
4   return hash(urlparse.urlparse(url).netloc)
5  
6 iteblog.partitionBy(20, iteblog_domain)

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

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

spark RDD算子(十三)之RDD 分区 HashPartitioner,RangePartitioner,自定义分区

关键字: spark分区方式,java HashPartitioner分区,scala HashPartitioner分区, java RangePartitioner 分区,scala RangeP...
  • T1DMzks
  • T1DMzks
  • 2017年05月07日 21:29
  • 1349

hadoop编程小技巧(3)---自定义分区类Partitioner

Hadoop代码测试环境:Hadoop2.4原理:在Hadoop的MapReduce过程中,Mapper读取处理完成数据后,会把数据发送到Partitioner,由Partitioner来决定每条记录...
  • fansy1990
  • fansy1990
  • 2014年07月17日 13:20
  • 2181

自定义Kafka分区器

自定义Kafka分区器
  • high2011
  • high2011
  • 2016年12月17日 12:05
  • 1913

学习Hadoop第十四课(自定义分区Partitioner)

上一节课我们一起学习了Hadoop的远程调试,这节课我们一起学习Hadoop的Partitioner(分区),首先说一下为什么要用到分区的功能,这里我们举个例子, 中国移动公司想要查看北京用户的打电...
  • u012453843
  • u012453843
  • 2016年10月10日 20:21
  • 861

Parallel中分区器Partitioner的简单使用

Partitioner.Create(1,10,4).GetDynamicPartitions()为长度为10的序列创建分区,每个分区至多4个元素,分区方法及结果:Partitioner.Create...
  • fuyifang
  • fuyifang
  • 2015年05月01日 20:54
  • 1646

Spark——数据分区(进阶)

对数据集在节点间的分区进行控制是Spark的一个特性之一。在分布式程序中通信的开销很大,和单节点的程序需要为记录集合选择合适的数据结构一样,Spark程序可以通过控制RDD分区方式来减少通信开销。只有...
  • zhaojw_420
  • zhaojw_420
  • 2016年11月30日 16:31
  • 2820

Partitioner分区过程分析

Partition的中文意思就是分区,分片的意思,这个阶段也是整个MapReduce过程的第三个阶段,就在Map任务的后面,他的作用就是使key分到通过一定的分区算法,分到固定的区域中,给不同的Red...
  • Androidlushangderen
  • Androidlushangderen
  • 2014年11月16日 14:48
  • 2663

spark 点滴:多路输出,自定义分区

多路输出: import org.apache.spark.{HashPartitioner, SparkContext, SparkConf} import org.apache.sp...
  • godspeedlaile9
  • godspeedlaile9
  • 2015年11月06日 14:57
  • 1220

改写Spark JdbcRDD,支持自己定义分区查询条件

自定义Spark JdbcRDD,支持更全面的自定义查询
  • yery
  • yery
  • 2015年02月06日 11:58
  • 2136
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Spark自定义分区(Partitioner)
举报原因:
原因补充:

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