Spark性能优化(1)——序列化、内存、并行度、数据存储格式、Shuffle
序列化
背景:
在以下过程中,需要对数据进行序列化:
- shuffling data时需要通过网络传输数据
- RDD序列化到磁盘时
性能优化点:
Spark默认的序列化类型是Java序列化。Java序列化的优势是兼容性好,不需要自已注册类。劣势是性能差。
为提升性能,建议使用Kryo序列化替代默认的Java序列化。
Kryo序列化的优势是速度快,体积小,劣势是兼容性差,需要自已注册类。
序列化的配置项:spark.serializer
- 使用方法1
1 |
val conf = new SparkConf().setMaster(...).setAppName(...) |
- 使用方法2
参考[Spark序列化与压缩]
注意:还外还有一个叫闭包序列化的配置项,此配置项只支持Java序列化:spark.closure.serializer
内存:容量规划
背景
Spark中负责具体计算任务的是executor。每个executor上的内存大小是可以配置的。从executor的内存中划出一定的比例用于RDD的缓存,其他内存用于Task的任务计算,比如保存新创建的对象等。executor的内存大小通过spark.executor.memory参数配置,默认是512M。上述比例通过spark.storage.memoryFraction参数配置,默认是0.6。即默认每个executor的内存是512M,其中512M*0.6=307.2M用于RDD缓存,其余 512M*0.4=204.8用于Task任务计算。
性能优化点:
- 如果executor报OOM内存不足,需要考虑增大spark.executor.memory。
如果频繁Full GC,可能是executor中用于Task任务计算的内存不足:
需要考虑降低spark.storage.memoryFraction的比例,即减小用于缓存的内存大小,增大用于Task任务计算的内存大小。
需要考虑优化RDD中的数据结构,减小数据占用的内存大小。如果频繁Minor GC, 需要考虑增大年轻代内存的大小。
相关点:
- 如何查看内存使用情况?
调用cache()进行缓存时,可以在日志中查看到RDD内存大小。此处应该还有其他办法可以查看,不可能要触发cache才能查看。
- 如何查看GC情况?
spark-env.sh 中设置 JAVA_OPTS 参数以打印 GC 的相关信息。这样如果有GC发生,就可以在master和work的日志上看到。
JAVA_OPTS=" -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps"
内存:优化数据结构
背景:通过优化RDD中存储的数据的数据结构,减小数据占用的内存空间大小。
性能优化点:
- 使用Set/Map等集合类型替代Iterator迭代器
Set/Map的查询速度接近O(1),而Iterator是O(n)
- 数据结构使用原始数据结构替代集合类
RDD中的数据结构使用Scala的原始数据结构替代List、Set等集合类,这样可以得到更好的性能。而fastutil库已经过优化,可以使用。
数据结构避免嵌套结构
数据结构避免使用String作为Key
Java中的String是常量,每个String需要额外占用几十个字节的空间,使用String作为Key效率不高。而且在shuffle过程中,需要比较Key。比较String效率不高。因此需要避免使用String作为Key。
内存:调整存储级别
默认的存储级别是MEMORY_ONLY,即以对象的形式只存储在内存中。如果内存不够用,一种优化方式是将存储级别改为MEMORYONLYSER。这种级别会在对象进行序列化后再存入内存,可以将占用的内存空间减小。
并行度:
背景1:Map Task的数量
RDD的map task的数量与Partition的数量相同。Partition的数量由创建Partition的方法中指定。
确定Partition数量的原则(优先级):
- 参数中的numPartitions参数(比如parallelize方法的第二个参数,reduceByKey、groupByKey等方法中的第二个参数)
- spark.default.parallelism参数
- 父RDD切片数
比如使用parallelize创建RDD,其Partition数量依如下顺序确定:
1. 方法的第二个参数 > 2. spark.default.parallelism参数 > 3. 按照“2-4 partitions for each CPU core”的 原则自动设置partition的数量。
比如使用textfile方法创建RDD:其Partition数量依如下顺序确定: 1. 方法的第二个参数(大于实际的block数量) > 2. block数量。如果是HDFS,block大小默认是64MB或128MB。
比如使用reduceByKey方法创建RDD:其Partition数量依如下顺序确定:1. 方法的第二个参数 > 2. spark.default.parallelism参数 > 3. 所有依赖的RDD中,Partition最多的RDD的Partition的数量。
背景2:
Spark进行并行计算时,同时进行计算的Task数量并不是并行度设置的值,而是整个集群的CPU核数。因为每个CPU核,每次只能处理一个任务。
性能优化点:
假设有360G的数据需要处理。当前有三台服务器,每台服务器32个CPU核心,每台服务器256G内存。 spark.executor.memory为128G,cache比例为0.6。则每台服务器可用于Task计算的内存为:128G * 0.4 = 76.8G。
此时,如果并行度设置为120。 则每台服务器上同时执行的Task数量为:32个(CPU核数)。 同时执行的Task占用的内存为:(360G/120)*32核=96GB——仅输入数据的大小,不含中间对象等其他内存占用 96GB > 76.8。所以,此时必然会内存不足。
解决办法,提高并行度。比如调整到360。则: 则每台服务器上同时执行的Task数量为:32个(CPU核数)。 同时执行的Task占用的内存为:(360G/360)*32核=32GB——仅输入数据的大小,不含中间对象等其他内存占用 32GB > 76.8。
数据存储格式
当Spark只读取文件中的部分列时,此时可以将文件的存储格式设计为采用列存储格式。这有助于提升数据读取性能。
Shuffle过程优化
背景
一般情况下,Shuffle过程中,需要N*M个文件(N是Map任务数,M是Shuffle任务数)。过多的中间文件,可能会导致性能下降。
性能优化点
通过如下配置,可以合并部分Shuffle中间文件,减少中间文件数量:
spark.shuffle.consolidateFiles=true
参考文档
Spark性能优化(1)——序列化、内存、并行度、数据存储格式、Shuffle的更多相关文章
- spark性能优化(包括优化原理及基本方法)
https://www.jianshu.com/p/b8841a8925fb spark性能优化 1.诊断内存的消耗 2. 高性能序列化类库 3. 优化数据结构 4. 对多次使用的rdd进行持久化或者 ...
- Spark性能优化:数据倾斜调优
前言 继<Spark性能优化:开发调优篇>和<Spark性能优化:资源调优篇>讲解了每个Spark开发人员都必须熟知的开发调优与资源调优之后,本文作为<Spark性能优化 ...
- 【转载】Spark性能优化指南——高级篇
前言 数据倾斜调优 调优概述 数据倾斜发生时的现象 数据倾斜发生的原理 如何定位导致数据倾斜的代码 查看导致数据倾斜的key的数据分布情况 数据倾斜的解决方案 解决方案一:使用Hive ETL预处理数 ...
- 【转】【技术博客】Spark性能优化指南——高级篇
http://mp.weixin.qq.com/s?__biz=MjM5NjQ5MTI5OA==&mid=2651745207&idx=1&sn=3d70d59cede236e ...
- Spark性能优化指南——高级篇(转载)
前言 继基础篇讲解了每个Spark开发人员都必须熟知的开发调优与资源调优之后,本文作为<Spark性能优化指南>的高级篇,将深入分析数据倾斜调优与shuffle调优,以解决更加棘手的性能问 ...
- Spark性能优化指南-高级篇
转自https://tech.meituan.com/spark-tuning-pro.html,感谢原作者的贡献 前言 继基础篇讲解了每个Spark开发人员都必须熟知的开发调优与资源调优之后,本文作 ...
- Spark性能优化指南——高级篇
本文转载自:https://tech.meituan.com/spark-tuning-pro.html 美团技术点评团队) Spark性能优化指南——高级篇 李雪蕤 ·2016-05-12 14:4 ...
- 【转载】 Spark性能优化指南——基础篇
转自:http://tech.meituan.com/spark-tuning-basic.html?from=timeline 前言 开发调优 调优概述 原则一:避免创建重复的RDD 原则二:尽可能 ...
- 【转】Spark性能优化指南——基础篇
http://mp.weixin.qq.com/s?__biz=MjM5NDMwNjMzNA==&mid=2651805828&idx=1&sn=2f413828d1fdc6a ...
随机推荐
- 设置Treeview背景色的问题1
有没有哪位兄弟在VB中使用sendmessage对TreeView改变背景色?我现在遇到一个问题,如果把linestyle设为1 的时候,展开节点的时候root部位会 有一个下拉的白色块,如果设为1 ...
- sql面试-查询选修课程的学生
首先: 1 . EXISTS 子查询找到的提交 NOT EXISTS 子查询中 找不到的提交 说明:不要去翻译为存在和不存在,把脑袋搞晕. 2 . 建立程序循环的概念,这是一个动态的查询过程.如 F ...
- Oracle-client支持exp|imp|rman
官方精简版的驱动,不支持持exp/imp/rman,故需要安装oracle_client客户端. 实验环境: Centos6.5 x64 Oracle 11.2.0.4.0 Oracle_clie ...
- Docker镜像仓库Harbor之搭建及配置
目录 Harbor介绍环境.软件准备Harbor服务搭建Harbor跨数据复制配置FAQ1.Harbor 介绍 Docker容器应用的开发和运行离不开可靠的镜像管理,虽然Docker官方也提供了公共的 ...
- 使用Python的turtle库实现七段数码管绘制
七段数码管绘制:七段数码管是由7段数码管拼接而成,每段有亮或不亮两种情况,改进的七段数码管还包括一个小数点位置.七段数码管能形成2=128种状态,其中部分状态能够显示易于人们理解的数字或字母含义.因此 ...
- PHP5.4新特性
PHP5.4 此次更新的关键新特性,包括:新增traits,更精简的Array数组语法,供测试使用的内建webserver,可以闭包使用的$this指针,实例化类成员访问, PHP 5.4.0 性能大 ...
- Android学习系列(9)--App列表之分组ListView
吸引用户的眼球,是我们至死不渝的追求: 第一时间呈现最有价值的信息,简明大方,告诉客户,你的选择是多么的明智,这正是你寻觅已久的东西. 分组的应用场合还是很多的,有数据集合的地方 ...
- jQuery on() 方法问题
<!DOCTYPE html><html><head><script src="https://cdn.bootcss.com/jquery/1.1 ...
- 如何利用JConsole观察分析JAVA程序的运行
今天在CSDN看到一朋友说关于对JVM的研究,正好看到有关于jconsole的文章,特意找了下资料,留着备用 ps:jconsole建议用JDK1.6的1.5的界面太简陋了,另外还有增强版jvisua ...
- Linux时间子系统(十三) Tick Device layer综述
一.前言 时间子系统中的tick device layer主要涉及kernel/time/tick-*相关的文件,本文的主要内容就是从high level层次(不纠缠在具体的每行代码)描述tick d ...