Spark学习之路 (十七)Spark分区[转]
分区的概念
分区是RDD内部并行计算的一个计算单元,RDD的数据集在逻辑上被划分为多个分片,每一个分片称为分区,分区的格式决定了并行计算的粒度,而每个分区的数值计算都是在一个任务中进行的,因此任务的个数,也是由RDD(准确来说是作业最后一个RDD)的分区数决定。
为什么要进行分区
数据分区,在分布式集群里,网络通信的代价很大,减少网络传输可以极大提升性能。mapreduce框架的性能开支主要在io和网络传输,io因为要大量读写文件,它是不可避免的,但是网络传输是可以避免的,把大文件压缩变小文件, 从而减少网络传输,但是增加了cpu的计算负载。
Spark里面io也是不可避免的,但是网络传输spark里面进行了优化:
Spark把rdd进行分区(分片),放在集群上并行计算。同一个rdd分片100个,10个节点,平均一个节点10个分区,当进行sum型的计算的时候,先进行每个分区的sum,然后把sum值shuffle传输到主程序进行全局sum,所以进行sum型计算对网络传输非常小。但对于进行join型的计算的时候,需要把数据本身进行shuffle,网络开销很大。
spark是如何优化这个问题的呢?
Spark把key-value rdd通过key的hashcode进行分区,而且保证相同的key存储在同一个节点上,这样对改rdd进行key聚合时,就不需要shuffle过程,我们进行mapreduce计算的时候为什么要进行shuffle?,就是说mapreduce里面网络传输主要在shuffle阶段,shuffle的根本原因是相同的key存在不同的节点上,按key进行聚合的时候不得不进行shuffle。shuffle是非常影响网络的,它要把所有的数据混在一起走网络,然后它才能把相同的key走到一起。要进行shuffle是存储决定的。
Spark从这个教训中得到启发,spark会把key进行分区,也就是key的hashcode进行分区,相同的key,hashcode肯定是一样的,所以它进行分区的时候100t的数据分成10分,每部分10个t,它能确保相同的key肯定在一个分区里面,而且它能保证存储的时候相同的key能够存在同一个节点上。比如一个rdd分成了100份,集群有10个节点,所以每个节点存10份,每一分称为每个分区,spark能保证相同的key存在同一个节点上,实际上相同的key存在同一个分区。
key的分布不均决定了有的分区大有的分区小。没法分区保证完全相等,但它会保证在一个接近的范围。所以mapreduce里面做的某些工作里边,spark就不需要shuffle了,spark解决网络传输这块的根本原理就是这个。
进行join的时候是两个表,不可能把两个表都分区好,通常情况下是把用的频繁的大表事先进行分区,小表进行关联它的时候小表进行shuffle过程。
大表不需要shuffle。
需要在工作节点间进行数据混洗的转换极大地受益于分区。这样的转换是 cogroup,groupWith,join,leftOuterJoin,rightOuterJoin,groupByKey,reduceByKey,combineByKey 和lookup。
分区是可配置的,只要RDD是基于键值对的即可。
Spark分区原则及方法
RDD分区的一个分区原则:尽可能是得分区的个数等于集群核心数目
无论是本地模式、Standalone模式、YARN模式或Mesos模式,我们都可以通过spark.default.parallelism来配置其默认分区个数,若没有设置该值,则根据不同的集群环境确定该值
本地模式
默认方式
以下这种默认方式就一个分区
结果
手动设置
设置了几个分区就是几个分区
结果
跟local[n] 有关
n等于几默认就是几个分区
如果n=* 那么分区个数就等于cpu core的个数
结果
参数控制
结果
YARN模式
进入defaultParallelism方法
继续进入defaultParallelism方法
这个一个trait,其实现类是(Ctrl+h)
进入TaskSchedulerImpl类找到defaultParallelism方法
继续进入defaultParallelism方法,又是一个trait,看其实现类
Ctrl+h看SchedulerBackend类的实现类
进入CoarseGrainedSchedulerBackend找到defaultParallelism
totalCoreCount.get()是所有executor使用的core总数,和2比较去较大值
如果正常的情况下,那你设置了多少就是多少
分区器
(1)如果是从HDFS里面读取出来的数据,不需要分区器。因为HDFS本来就分好区了。
分区数我们是可以控制的,但是没必要有分区器。
(2)非key-value RDD分区,没必要设置分区器
al testRDD = sc.textFile("C:\\Users\\Administrator\\IdeaProjects\\myspark\\src\\main\\hello.txt")
.flatMap(line => line.split(","))
.map(word => (word, 1)).partitionBy(new HashPartitioner(2))
没必要设置,但是非要设置也行。
(3)Key-value形式的时候,我们就有必要了。
HashPartitioner
val resultRDD = testRDD.reduceByKey(new HashPartitioner(2),(x:Int,y:Int) => x+ y)
//如果不设置默认也是HashPartitoiner,分区数跟spark.default.parallelism一样
println(resultRDD.partitioner)
println("resultRDD"+resultRDD.getNumPartitions)
RangePartitioner
val resultRDD = testRDD.reduceByKey((x:Int,y:Int) => x+ y)
val newresultRDD=resultRDD.partitionBy(new RangePartitioner[String,Int](3,resultRDD))
println(newresultRDD.partitioner)
println("newresultRDD"+newresultRDD.getNumPartitions)
注:按照范围进行分区的,如果是字符串,那么就按字典顺序的范围划分。如果是数字,就按数据自的范围划分。
自定义分区
需要实现2个方法
class MyPartitoiner(val numParts:Int) extends Partitioner{
override def numPartitions: Int = numParts
override def getPartition(key: Any): Int = {
val domain = new URL(key.toString).getHost
val code = (domain.hashCode % numParts)
if (code < 0) {
code + numParts
} else {
code
}
}
}
object DomainNamePartitioner {
def main(args: Array[String]): Unit = {
val conf = new SparkConf().setAppName("word count").setMaster("local")
val sc = new SparkContext(conf)
val urlRDD = sc.makeRDD(Seq(("http://baidu.com/test", 2),
("http://baidu.com/index", 2), ("http://ali.com", 3), ("http://baidu.com/tmmmm", 4),
("http://baidu.com/test", 4)))
//Array[Array[(String, Int)]]
// = Array(Array(),
// Array((http://baidu.com/index,2), (http://baidu.com/tmmmm,4),
// (http://baidu.com/test,4), (http://baidu.com/test,2), (http://ali.com,3)))
val hashPartitionedRDD = urlRDD.partitionBy(new HashPartitioner(2))
hashPartitionedRDD.glom().collect()
//使用spark-shell --jar的方式将这个partitioner所在的jar包引进去,然后测试下面的代码
// spark-shell --master spark://master:7077 --jars spark-rdd-1.0-SNAPSHOT.jar
val partitionedRDD = urlRDD.partitionBy(new MyPartitoiner(2))
val array = partitionedRDD.glom().collect()
}
}
Spark学习之路 (十七)Spark分区[转]的更多相关文章
- [转]Spark学习之路 (三)Spark之RDD
Spark学习之路 (三)Spark之RDD https://www.cnblogs.com/qingyunzong/p/8899715.html 目录 一.RDD的概述 1.1 什么是RDD? ...
- Spark学习笔记2(spark所需环境配置
Spark学习笔记2 配置spark所需环境 1.首先先把本地的maven的压缩包解压到本地文件夹中,安装好本地的maven客户端程序,版本没有什么要求 不需要最新版的maven客户端. 解压完成之后 ...
- Spark学习之路 (二十三)SparkStreaming的官方文档
一.SparkCore.SparkSQL和SparkStreaming的类似之处 二.SparkStreaming的运行流程 2.1 图解说明 2.2 文字解说 1.我们在集群中的其中一台机器上提交我 ...
- Spark学习之路 (八)SparkCore的调优之开发调优
摘抄自:https://tech.meituan.com/spark-tuning-basic.html 前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark ...
- Spark学习之路 (三)Spark之RDD
一.RDD的概述 1.1 什么是RDD? RDD(Resilient Distributed Dataset)叫做弹性分布式数据集,是Spark中最基本的数据抽象,它代表一个不可变.可分区.里面的元素 ...
- Spark学习之路 (二十二)SparkStreaming的官方文档
官网地址:http://spark.apache.org/docs/latest/streaming-programming-guide.html 一.简介 1.1 概述 Spark Streamin ...
- Spark学习之路(十六)—— Spark Streaming 整合 Kafka
一.版本说明 Spark针对Kafka的不同版本,提供了两套整合方案:spark-streaming-kafka-0-8和spark-streaming-kafka-0-10,其主要区别如下: s ...
- Spark学习之路(十四)—— Spark Streaming 基本操作
一.案例引入 这里先引入一个基本的案例来演示流的创建:获取指定端口上的数据并进行词频统计.项目依赖和代码实现如下: <dependency> <groupId>org.apac ...
- Spark学习之路(十一)—— Spark SQL 聚合函数 Aggregations
一.简单聚合 1.1 数据准备 // 需要导入spark sql内置的函数包 import org.apache.spark.sql.functions._ val spark = SparkSess ...
- Spark学习之路 (二十三)SparkStreaming的官方文档[转]
SparkCore.SparkSQL和SparkStreaming的类似之处 SparkStreaming的运行流程 1.我们在集群中的其中一台机器上提交我们的Application Jar,然后就会 ...
随机推荐
- 看完这篇文章,再次遇到Jedis「Redis客户端」异常相信你不再怕了!
本文导读: [1] 疫情当前 [2] 应用异常监控 [3] Redis客户端异常分析 [4] Redis客户端问题引导分析 [5] 站在Redis客户端视角分析 [6] 站在Redis服务端视角分析 ...
- 视觉slam十四讲第8章课后习题3+稀疏直接法程序注释
版权声明:本文为博主原创文章,转载请注明出处: http://www.cnblogs.com/newneul/p/8571653.html 3.题目回顾:在稀疏直接法中,假设单个像素周围小块的光度也不 ...
- Codeforces_814
A.b序列从大到小填a序列中的0,在判断. #include<bits/stdc++.h> using namespace std; ],b[]; int main() { ios::sy ...
- java Map排序问题
java 中,Map常见的有HashMap ,TreeMap等等,Map是一个接口,我们不能直接声明一个Map类型的对象,在实际开发 中,比较常用的Map性数据结构是HashMap和TreeMap,它 ...
- 51nod 1133 不重叠的线段 (贪心,序列上的区间问题)
题意: 最多能选几条不重叠的线段 思路: 按R从小到大排序,维护一个最大的右端点 右端点最小的那个线段是必选的,可以贪心地证明 代码: #include<iostream> #includ ...
- 曹工说Spring Boot源码(17)-- Spring从xml文件里到底得到了什么(aop:config完整解析【中】)
写在前面的话 相关背景及资源: 曹工说Spring Boot源码(1)-- Bean Definition到底是什么,附spring思维导图分享 曹工说Spring Boot源码(2)-- Bean ...
- Spring Boot2 系列教程(三十二)Spring Boot 整合 Shiro
在 Spring Boot 中做权限管理,一般来说,主流的方案是 Spring Security ,但是,仅仅从技术角度来说,也可以使用 Shiro. 今天松哥就来和大家聊聊 Spring Boot ...
- webpack chunkFilename 非入口文件的命名规则 [转]
官网的文档只理解了filename是主入口的文件名,chunkFilename是非主入口的文件名 filename应该比较好理解,就是对应于entry里面生成出来的文件名.比如: { entry: { ...
- Linux学习1-云服务器上搭建禅道项目管理工具
前言 相信各位测试的小伙伴出去面试总会被问到:测试环境怎么搭建?一个中级测试工程师还是对测试环境一无所知的话,面试官会一脸鄙视的,今天我给大家介绍一下最简单的环境部署-—如何在云服务器部署禅道环境. ...
- PyObject and PyTypeObject - Python 中的 '对象' 们
1 PyObject, PyTypeObject - Python 中的 '对象' 们 '一切皆对象' - 这是 Python 的学习和使用者们最最常听到一句, 可谓 博大精深 - '勃大精深'. ' ...