在spark中,框架默认使用的事hashPartitioner分区器进行对rdd分区,但是实际生产中,往往使用spark自带的分区器会产生数据倾斜等原因,这个时候就需要我们自定义分区,按照我们指定的字段进行分区。具体的流程步骤如下:

1、创建一个自定义的分区类,并继承Partitioner,注意这个partitioner是spark的partitioner

2、重写partitioner中的方法

  override def numPartitions: Int = ???
override def getPartition(key: Any): Int = ??? 代码实现:
测试数据集:
cookieid,createtime,pv
cookie1,2015-04-10,1
cookie1,2015-04-11,5
cookie1,2015-04-12,7
cookie1,2015-04-13,3
cookie1,2015-04-14,2
cookie1,2015-04-15,4
cookie1,2015-04-16,4
cookie2,2015-04-10,2
cookie2,2015-04-11,3
cookie2,2015-04-12,5
cookie2,2015-04-13,6
cookie2,2015-04-14,3
cookie2,2015-04-15,9
cookie2,2015-04-16,7

  指定按照第一个字段进行分区

步骤1:
package _core.sourceCodeLearning.partitioner

import org.apache.spark.Partitioner
import scala.collection.mutable.HashMap /**
* Author Mr. Guo
* Create 2019/6/23 - 12:19
*/
class UDFPartitioner(args: Array[String]) extends Partitioner { private val partitionMap: HashMap[String, Int] = new HashMap[String, Int]()
var parId = 0
for (arg <- args) {
if (!partitionMap.contains(arg)) {
partitionMap(arg) = parId
parId += 1
}
} override def numPartitions: Int = partitionMap.valuesIterator.length override def getPartition(key: Any): Int = {
val keys: String = key.asInstanceOf[String]
val sub = keys
partitionMap(sub)
}
}

  步骤2:

主类测试:

package _core.sourceCodeLearning.partitioner

import org.apache.spark.{SparkConf, TaskContext}
import org.apache.spark.sql.SparkSession /**
* Author Mr. Guo
* Create 2019/6/23 - 12:21
*/
object UDFPartitionerMain {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setMaster("local[2]").setAppName(this.getClass.getSimpleName)
val ssc = SparkSession
.builder()
.config(conf)
.getOrCreate()
val sc = ssc.sparkContext
sc.setLogLevel("WARN") val rdd = ssc.sparkContext.textFile("file:///E:\\TestFile\\analyfuncdata.txt")
val transform = rdd.filter(_.split(",").length == 3).map(x => {
val arr = x.split(",")
(arr(0), (arr(1), arr(2)))
})
val keys: Array[String] = transform.map(_._1).collect()
val partiion = transform.partitionBy(new UDFPartitioner(keys))
partiion.foreachPartition(iter => {
println(s"**********分区号:${TaskContext.getPartitionId()}***************")
iter.foreach(r => {
println(s"分区:${TaskContext.getPartitionId()}###" + r._1 + "\t" + r._2 + "::" + r._2._1)
})
})
ssc.stop()
}
}

  运行结果:

这样就是按照第一个字段进行了分区,当然在分区器的中,对于key是可以根据自己的需求随意的处理,比如添加随机数等等

spark自定义分区器实现的更多相关文章

  1. Spark自定义分区(Partitioner)

    我们都知道Spark内部提供了HashPartitioner和RangePartitioner两种分区策略,这两种分区策略在很多情况下都适合我们的场景.但是有些情况下,Spark内部不能符合咱们的需求 ...

  2. MapReduce之自定义分区器Partitioner

    @ 目录 问题引出 默认Partitioner分区 自定义Partitioner步骤 Partition分区案例实操 分区总结 问题引出 要求将统计结果按照条件输出到不同文件中(分区). 比如:将统计 ...

  3. kafka 自定义分区器

    package cn.xiaojf.kafka.producer; import org.apache.kafka.clients.producer.Partitioner; import org.a ...

  4. Spark源码分析之分区器的作用

    最近因为手抖,在Spark中给自己挖了一个数据倾斜的坑.为了解决这个问题,顺便研究了下Spark分区器的原理,趁着周末加班总结一下~ 先说说数据倾斜 数据倾斜是指Spark中的RDD在计算的时候,每个 ...

  5. RDD(六)——分区器

    RDD的分区器 Spark目前支持Hash分区和Range分区,用户也可以自定义分区,Hash分区为当前的默认分区,Spark中分区器直接决定了RDD中分区的个数.RDD中每条数据经过Shuffle过 ...

  6. 聊聊Spark的分区、并行度 —— 前奏篇

    通过之前的文章[Spark RDD详解],大家应该了解到Spark会通过DAG将一个Spark job中用到的所有RDD划分为不同的stage,每个stage内部都会有很多子任务处理数据,而每个sta ...

  7. 玩转Kafka的生产者——分区器与多线程

    上篇文章学习kafka的基本安装和基础概念,本文主要是学习kafka的常用API.其中包括生产者和消费者, 多线程生产者,多线程消费者,自定义分区等,当然还包括一些避坑指南. 首发于个人网站:链接地址 ...

  8. kafka producer partitions分区器(七)

    消息在经过拦截器.序列化后,就需要确定它发往哪个分区,如果在ProducerRecord中指定了partition字段,那么就不再需要partitioner分区器进行分区了,如果没有指定,那么会根据k ...

  9. Kafka的接口回调 +自定义分区、拦截器

    一.接口回调+自定义分区 1.接口回调:在使用消费者的send方法时添加Callback回调 producer.send(new ProducerRecord<String, String> ...

随机推荐

  1. 人生苦短,我学PYTHON

    人生苦短我学PYTHON 坚持 努力

  2. 与JS报错的那段时光

    1.Uncaught SyntaxError: Unexpected end of input js报错: 翻译:语法错误:输入意外终止 原因:页面代码写的不规范  ╮(╯▽╰)╭ 其中的某条语句,没 ...

  3. Draggable(拖动框)

    一.class加载方式 <div id="box" class="easyui-draggable" style="width:400px;he ...

  4. flex布局(弹性布局)

    1. 传统布局与 flex 布局比较 传统布局 兼容性好 布局繁琐 局限性,不能在移动端很好的布局 flex 弹性布局 操作方便,布局极为简单,移动端应用很广泛 PC端浏览器支持较差 IE 11 或 ...

  5. KiCAD差分布线

    KiCAD差分布线方法 KiCAD在进行差分布线的时候,会自动按照网路名称生成差分对,所以差分对的名称必须是以_P_N或+/-结束,这样才能找到一对差分对,比如说CAN网络,可以定义为CAN_P/CA ...

  6. ZedGraph怎样在生成曲线时随机生成不一样的颜色

    场景 在使用ZedGraph生成多条曲线时为了能区分曲线颜色,要求随机设置曲线颜色. 首先从System.Drawing.Color中获取所有颜色的对象的数组,然后将其顺序打乱随机排序,然后在生成曲线 ...

  7. 搭建appium+maven手机自动化测试环境搭建

    搭建安卓自动化测试框架记录: 需要的软件: jdk版本:jdk1.8 appium版本:v1.4.16 下载AppiumForWindows.zip (下载appium1.7不需要配置环境变量) no ...

  8. Java中的时间日期Date和Calendar

    日期时间类 Date: Date类的构造方法: 可以发现Date类的toString方法被重写了. Date类的方法: SimpleDateFormat 它提供了解决Date输出问题的解决方案--格式 ...

  9. 【LeetCode 4】寻找两个有序数组的中位数

    题目链接 [题解] 假设在两个有序的序列中找第k小的数字. 那么我们先定位第一个序列中的第k/2个数字(不足则取最边上的那个数字)记下标为i1 然后定位第二个序列中的第k/2个数字(同样不足则取最边上 ...

  10. Dubbo 如何成为连接异构微服务体系的最佳服务开发框架

    从编程开发的角度来说,Apache Dubbo (以下简称 Dubbo)首先是一款 RPC 服务框架,它最大的优势在于提供了面向接口代理的服务编程模型,对开发者屏蔽了底层的远程通信细节.同时 Dubb ...