RDD(六)——分区器
RDD的分区器
Spark目前支持Hash分区和Range分区,用户也可以自定义分区,Hash分区为当前的默认分区,Spark中分区器直接决定了RDD中分区的个数、RDD中每条数据经过Shuffle过程属于哪个分区和Reduce的个数。
注意:
(1)只有Key-Value类型的RDD才有分区器的,非Key-Value类型的RDD分区器的值是None
(2)每个RDD的分区ID范围:0~numPartitions-1,决定这个值是属于那个分区的。
Hash分区
HashPartitioner分区的原理:对于给定的key,计算其hashCode,并除以分区的个数取余,如果余数小于0,则用余数+分区的个数(否则加0),最后返回的值就是这个key所属的分区ID。
查看hash分区原码如下:
*/
class HashPartitioner(partitions: Int) extends Partitioner {
require(partitions >= 0, s"Number of partitions ($partitions) cannot be negative.") def numPartitions: Int = partitions def getPartition(key: Any): Int = key match {
case null => 0//key为0则统统放入0号分区
case _ => Utils.nonNegativeMod(key.hashCode, numPartitions)
//否则调用这个方法,根据key的hashcode和分区数,得到分区号
}
def nonNegativeMod(x: Int, mod: Int): Int = {
val rawMod = x % mod
rawMod + (if (rawMod < 0) mod else 0)
}
ranger分区
HashPartitioner分区弊端:可能导致每个分区中数据量的不均匀,极端情况下会导致某些分区拥有RDD的全部数据。
RangePartitioner作用:将一定范围内的数映射到某一个分区内,尽量保证每个分区中数据量的均匀,而且分区与分区之间是有序的,一个分区中的元素肯定都是比另一个分区内的元素小或者大,但是分区内的元素是不能保证顺序。简单的说就是将一定范围内的数映射到某一个分区内。实现过程为:
第一步:先从整个RDD中抽取出样本数据,将样本数据排序,计算出每个分区的最大key值,形成一个Array[KEY]类型的数组变量rangeBounds;
第二步:判断key在rangeBounds中所处的范围,给出该key值在RDD中的分区id下标;该分区器要求RDD中的KEY类型必须是可以排序的
自定义分区器
要实现自定义的分区器,你需要继承 org.apache.spark.Partitioner 类并实现下面两个个方法。
(1)numPartitions: Int:返回创建出来的分区数。
(2)getPartition(key: Any): Int:返回给定键的分区编号(0到numPartitions-1)。
示例代码如下:将key对分区数求余数,得到分区号。
package partitioner import org.apache.spark.Partitioner class MyPartitioner(partitions:Int) extends Partitioner{ override def numPartitions: Int = {
return partitions;
} override def getPartition(key: Any): Int = { val mykey : Int = key.asInstanceOf;
//val i: Int = key.asInstanceOf[Int]
return mykey%partitions ;
}
} def main(args: Array[String]): Unit = { val sc: SparkContext = new SparkContext(new SparkConf()
.setMaster("local[*]").setAppName("spark")) val raw: RDD[(Int, String)] = sc.makeRDD(Array((1, "a"), (2, "b"), (3, "c"), (4, "d")))
raw.saveAsTextFile("E:/idea/spark2/out/partitioner_before") val partitionedRDD: RDD[(Int, String)] = raw.partitionBy(new MyPartitioner(2))
println(partitionedRDD.partitioner)
partitionedRDD.saveAsTextFile("E:/idea/spark2/out/partitioner_after")
}
查看分区后数据的分布:
0号文件:(2,b)(4,d)
1号文件:(1,a)(3,c)
使用自定义的 Partitioner 是很容易的:只要把它传给 partitionBy() 方法即可。Spark 中有许多依赖于数据混洗的方法,比如 join() 和 groupByKey(),它们也可以接收一个可选的 Partitioner 对象来控制输出数据的分区方式。
RDD(六)——分区器的更多相关文章
- Spark分区器浅析
分区器作用:决定该数据在哪个分区 概览: 仅仅只有pairRDD才可能持有分区器,普通RDD的分区器为None 在分区器为None时RDD分区一般继承至父RDD分区 初始RDD分区数: 由集合创建,R ...
- Spark(九)【RDD的分区和自定义Partitioner】
目录 spark的分区 一. Hash分区 二. Ranger分区 三. 自定义Partitioner 案例 spark的分区 Spark目前支持Hash分区和Range分区,用户也可以自定义分区 ...
- 大数据学习day19-----spark02-------0 零碎知识点(分区,分区和分区器的区别) 1. RDD的使用(RDD的概念,特点,创建rdd的方式以及常见rdd的算子) 2.Spark中的一些重要概念
0. 零碎概念 (1) 这个有点疑惑,有可能是错误的. (2) 此处就算地址写错了也不会报错,因为此操作只是读取数据的操作(元数据),表示从此地址读取数据但并没有进行读取数据的操作 (3)分区(有时间 ...
- Spark源码分析之分区器的作用
最近因为手抖,在Spark中给自己挖了一个数据倾斜的坑.为了解决这个问题,顺便研究了下Spark分区器的原理,趁着周末加班总结一下~ 先说说数据倾斜 数据倾斜是指Spark中的RDD在计算的时候,每个 ...
- RDD的分区相关
分区是rdd的一个属性,每个分区是一个迭代器 分区器是决定数据数据如何分区 RDD划分成许多分区分布到集群的节点上,分区的多少涉及对这个RDD进行并行计算的粒度.用户可以获取分区数和设置分区数目,默认 ...
- 028 Partitioner:数据分区器
Partitioner:数据分区器,决定数据到下一个RDD的时候在那一个分区 HashPartitioner:根据key的hashCode值来实现 RangePartitioner: 根据key所属范 ...
- spark自定义分区器实现
在spark中,框架默认使用的事hashPartitioner分区器进行对rdd分区,但是实际生产中,往往使用spark自带的分区器会产生数据倾斜等原因,这个时候就需要我们自定义分区,按照我们指定的字 ...
- Cassandra1.2文档学习(4)——分区器
参考文档:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/a ...
- cassandra 3.x官方文档(4)---分区器
写在前面 cassandra3.x官方文档的非官方翻译.翻译内容水平全依赖本人英文水平和对cassandra的理解.所以强烈建议阅读英文版cassandra 3.x 官方文档.此文档一半是翻译,一半是 ...
随机推荐
- 【LeetCode】分发糖果
[问题]老师想给孩子们分发糖果,有 N 个孩子站成了一条直线,老师会根据每个孩子的表现,预先给他们评分. 你需要按照以下要求,帮助老师给这些孩子分发糖果: 每个孩子至少分配到 1 个糖果.相邻的孩子中 ...
- c++ STD Gems07
reverse.rotate.permutation #include <iostream> #include <vector> #include <string> ...
- C++中substr()详解
#include<string> #include<iostream> using namespace std; int main() { string s("123 ...
- Java 语言特性【一】——JUC(Java 并发工具包)
引言 JUC即java.util.concurrent,是java提供的用于多线程处理的工具类库.重点关注 ConcurrentXXX.AtomicXXX.Executor.Caller&&a ...
- Ubuntu13.04闪屏的问题
我的电脑Y460,双显切换,win7+ubuntu双系统,就是这个坑爹的双显切换,导致安装ubuntu13.04后屏老闪,网上查阅资料得知是显卡问题,一种是说显卡驱动问题,一种是说双显卡问题,双显卡问 ...
- rabbitmq安装及简单demo练习
参考:https://my.oschina.net/loveorange/blog/3026473 安装参考链接: 1. 下载自己需要的rabbitmq_server(http://www.rabbi ...
- 牛逼了,用Python破解wifi密码
Python真的是无所不能,原因就是因为Python有数目庞大的库,无数的现成的轮子,让你做很多很多应用都非常方便.wifi跟我们的生活息息相关,无处不在.今天从WiFi连接的原理,再结合代码为大家详 ...
- iris数据集预测
iris数据集预测(对比随机森林和逻辑回归算法) 随机森林 library(randomForest) #挑选响应变量 index <- subset(iris,Species != " ...
- Cpp:"->"和"."的区别
environments:gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project) class data{ publi ...
- redis(一)----配置及安装
1. redis下载 根据自己操作系统平台下载适合的文件包: https://github.com/MSOpenTech/redis 2. redis安装 (1)解压, ...