Spark自定义分区(Partitioner)
我们都知道Spark内部提供了HashPartitioner和RangePartitioner两种分区策略,这两种分区策略在很多情况下都适合我们的场景。但是有些情况下,Spark内部不能符合咱们的需求,这时候我们就可以自定义分区策略。为此,Spark提供了相应的接口,我们只需要扩展Partitioner抽象类,然后实现里面的三个方法:
package org.apache.spark
/**
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
*/
abstract class Partitioner extends Serializable {
def numPartitions: Int
def getPartition(key: Any): Int
}
def numPartitions: Int:这个方法需要返回你想要创建分区的个数;
def getPartition(key: Any): Int:这个函数需要对输入的key做计算,然后返回该key的分区ID,范围一定是0到numPartitions-1;
equals():这个是Java标准的判断相等的函数,之所以要求用户实现这个函数是因为Spark内部会比较两个RDD的分区是否一样。
假如我们想把来自同一个域名的URL放到一台节点上,比如:http://www.iteblog.com和http://www.iteblog.com/archives/1368,如果你使用HashPartitioner,这两个URL的Hash值可能不一样,这就使得这两个URL被放到不同的节点上。所以这种情况下我们就需要自定义我们的分区策略,可以如下实现:
package com.iteblog.utils
import org.apache.spark.Partitioner
/**
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
*/
class IteblogPartitioner(numParts: Int) extends Partitioner {
override def numPartitions: Int = numParts
override def getPartition(key: Any): Int = {
val domain = new java.net.URL(key.toString).getHost()
val code = (domain.hashCode % numPartitions)
if (code < ) {
code + numPartitions
} else {
code
}
}
override def equals(other: Any): Boolean = other match {
case iteblog: IteblogPartitioner =>
iteblog.numPartitions == numPartitions
case _ =>
false
}
override def hashCode: Int = numPartitions
}
因为hashCode值可能为负数,所以我们需要对他进行处理。然后我们就可以在partitionBy()方法里面
使用我们的分区:
iteblog.partitionBy(new IteblogPartitioner())
类似的,在Java中定义自己的分区策略和Scala类似,只需要继承org.apache.spark.Partitioner,并实现其中的方法即可。
在Python中,你不需要扩展Partitioner类,我们只需要对iteblog.partitionBy()加上一个额外的hash函数,如下:
import urlparse
def iteblog_domain(url):
return hash(urlparse.urlparse(url).netloc)
iteblog.partitionBy(, iteblog_domain)
Spark自定义分区(Partitioner)的更多相关文章
- spark自定义分区器实现
在spark中,框架默认使用的事hashPartitioner分区器进行对rdd分区,但是实际生产中,往往使用spark自带的分区器会产生数据倾斜等原因,这个时候就需要我们自定义分区,按照我们指定的字 ...
- 大数据入门第二十二天——spark(三)自定义分区、排序与查找
一.自定义分区 1.概述 默认的是Hash的分区策略,这点和Hadoop是类似的,具体的分区介绍,参见:https://blog.csdn.net/high2011/article/details/6 ...
- 自定义实现spark的分区函数
有时自己的业务需要自己实现spark的分区函数 以下代码是实现一个自定义spark分区的demo 实现的功能是根据key值的最后一位数字,写到不同的文件 例如: 10写入到part-00000 11写 ...
- MapReduce之自定义分区器Partitioner
@ 目录 问题引出 默认Partitioner分区 自定义Partitioner步骤 Partition分区案例实操 分区总结 问题引出 要求将统计结果按照条件输出到不同文件中(分区). 比如:将统计 ...
- Spark API--Spark 分区
一.分区的概念 分区是RDD内部并行计算的一个计算单元,RDD的数据集在逻辑上被划分为多个分片,每一个分片称为分区,分区的格式决定了并行计算的粒度,而每个分区的数值计算都是在一个任务中进行的,因此任务 ...
- 聊聊Spark的分区、并行度 —— 前奏篇
通过之前的文章[Spark RDD详解],大家应该了解到Spark会通过DAG将一个Spark job中用到的所有RDD划分为不同的stage,每个stage内部都会有很多子任务处理数据,而每个sta ...
- kafka 自定义分区器
package cn.xiaojf.kafka.producer; import org.apache.kafka.clients.producer.Partitioner; import org.a ...
- Kafka的接口回调 +自定义分区、拦截器
一.接口回调+自定义分区 1.接口回调:在使用消费者的send方法时添加Callback回调 producer.send(new ProducerRecord<String, String> ...
- [MapReduce_8] MapReduce 中的自定义分区实现
0. 说明 设置分区数量 && 编写自定义分区代码 1. 设置分区数量 分区(Partition) 分区决定了指定的 Key 进入到哪个 Reduce 中 分区目的:把相同的 Key ...
随机推荐
- Flexigrid例子二: 原位编辑器
有时候,我们想要编辑flexigrid里的数据.一个原位编辑器是需要的,现在不需要再弹出一个对话框了.这里我会展示如何做到这点. 我使用了jquery-in-place-editor库.请参考官方站点 ...
- 链表:删除链表中重复的结点(java实现)
题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...
- 函数变量作用域(python)
收集参数:该参数个数不确定 >>> def test(*params): print('参数的长度是:', len(params)); print('第二个参数是:', params ...
- docker-tomcat-nginx 反向代理和负载均衡
1.部署tomcat镜像 下载官方的tomcat镜像. -jre7 启动docker容器,2个实例,分别映射不同的端口号, ~/work/sample-webapps/[v1.0|v2.0]/下面存放 ...
- 如何制作prezi swf格式字体(prezi 中文字体)
如何制作prezi swf格式字体(prezi 中文字体) 文/玄魂 前言 Prezi软件虽然没有正式进入中国,但是中国的Prezi爱好者却在不遗余力的推广着Prezi.我接触这款软件比较晚,但是从接 ...
- c# 清空txt文本文件的值
FileStream fs1 = null; try { fs1 = new FileStream(@"C:\db.txt", FileMode.Truncate, FileAcc ...
- matlab读取txt文档中的数据
ps:文件中只有数字! format long fp=fopen('文件路径','打开方式(r)') [num,count]=fscnaf(fp,'%f')
- 操作笔记:linux下查看端口被占用
[root@iZ945sgm0ugZ /]# lsof -i:8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME java 1192 jet ...
- 操作笔记:linux下安装ftp
1,安装ftp [root@iZ945sgm0ugZ ~]# yum install vsftpd 安装成功的信息: [root@iZ945sgm0ugZ ~]# yum install vsftpd ...
- java排序练习
public void testSort3(){ List<String> str=new ArrayList<String>(); String st="12345 ...