您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
Spark性能调优
 
作者 程序员电子刊 来源:程序员电子刊 火龙果软件  发布于 2015-7-13
  2370  次浏览      50
 

摘要:通常我们对一个系统进行性能优化无怪乎两个步骤——性能监控和参数调整,本文主要分享的也是这两方面内容。

通常我们对一个系统进行性能优化无怪乎两个步骤——性能监控和参数调整,本文主要分享的也是这两方面内容。

性能监控工具

【Spark监控工具】

Spark提供了一些基本的Web监控页面,对于日常监控十分有用。

1. Application Web UI

http://master:4040(默认端口是4040,可以通过spark.ui.port修改)可获得这些信息:(1)stages和tasks调度情况;(2)RDD大小及内存使用;(3)系统环境信息;(4)正在执行的executor信息。

2. history server

当Spark应用退出后,仍可以获得历史Spark应用的stages和tasks执行信息,便于分析程序不明原因挂掉的情况。配置方法如下:

(1)$SPARK_HOME/conf/spark-env.sh

export SPARK_HISTORY_OPTS="-Dspark.history.retainedApplications=50

Dspark.history.fs.logDirectory=hdfs://hadoop000:8020/directory"

说明:spark.history.retainedApplica-tions仅显示最近50个应用spark.history.fs.logDirectory:Spark History Server页面只展示该路径下的信息。

(2)$SPARK_HOME/conf/spark-defaults.conf

spark.eventLog.enabled true

spark.eventLog.dir hdfs://hadoop000:8020/directory #应用在运行过程中所有的信息均记录在该属性指定的路径下

3. spark.eventLog.compress true

(1)HistoryServer启动

$SPARK_HOMR/bin/start-histrory-server.sh

(2)HistoryServer停止

$SPARK_HOMR/bin/stop-histrory-server.sh

4. ganglia

通过配置ganglia,可以分析集群的使用状况和资源瓶颈,但是默认情况下ganglia是未被打包的,需要在mvn编译时添加-Pspark-ganglia-lgpl,并修改配置文件$SPARK_HOME/conf/metrics.properties。

5. Executor logs

Standalone模式:$SPARK_HOME/logs

YARN模式:在yarn-site.xml文件中配置了YARN日志的存放位置:yarn.nodemanager.log-dirs,或使用命令获取yarn logs -applicationId。

【其他监控工具】

1. Nmon(http://www.ibm.com/developerworks/aix/library/au-analyze_aix/)

Nmon 输入:c:CPU n:网络 m:内存 d:磁盘

2. Jmeter(http://jmeter. apache.org/)

通常使用Jmeter做系统性能参数的实时展示,JMeter的安装非常简单,从官方网站上下载,解压之后即可使用。运行命令在%JMETER_HOME%/bin下,对于 Windows 用户,直接使用jmeter.bat。

启动jmeter:创建测试计划,设置线程组设置循环次数。

添加监听器:jp@gc - PerfMon Metrics Collector。

设置监听器:监听主机端口及监听内容,例如CPU。

启动监听:可以实时获得节点的CPU状态信息,从图4可看出CPU已出现瓶颈。

3. Jprofiler(http://www.ej-technologies.com/products/jprofiler/overview.html)

JProfiler是一个全功能的Java剖析工具(profiler),专用于分析J2SE和J2EE应用程式。它把CPU、线程和内存的剖析组合在一个强大的应用中。JProfiler的GUI可以更方便地找到性能瓶颈、抓住内存泄漏(memory leaks),并解决多线程的问题。例如分析哪个对象占用的内存比较多;哪个方法占用较大的CPU资源等;我们通常使用Jprofiler来监控Spark应用在local模式下运行时的性能瓶颈和内存泄漏情况。

上述几个工具可以直接通过提供的链接了解详细的使用方法。

Spark调优

【Spark集群并行度】

在Spark集群环境下,只有足够高的并行度才能使系统资源得到充分的利用,可以通过修改spark-env.sh来调整Executor的数量和使用资源,Standalone和YARN方式资源的调度管理是不同的。

在Standalone模式下:

1. 每个节点使用的最大内存数:SPARK_WORKER_INSTANCES*SPARK_WORKER_MEMORY;

2. 每个节点的最大并发task数:SPARK_WORKER_INSTANCES*SPARK_WORKER_CORES。

在YARN模式下:

1. 集群task并行度:SPARK_ EXECUTOR_INSTANCES* SPARK_EXECUTOR_CORES;

2. 集群内存总量:(executor个数) * (SPARK_EXECUTOR_MEMORY+ spark.yarn.executor.memoryOverhead)
+(SPARK_DRIVER_MEMORY+spark.yarn.driver.memoryOverhead)。

重点强调:Spark对Executor和Driver额外添加堆内存大小,Executor端:由spark.yarn.executor.memoryOverhead设置,默认值executorMemory * 0.07与384的最大值。Driver端:由spark.yarn.driver.memoryOverhead设置,默认值driverMemory * 0.07与384的最大值。

通过调整上述参数,可以提高集群并行度,让系统同时执行的任务更多,那么对于相同的任务,并行度高了,可以减少轮询次数。举例说明:如果一个stage有100task,并行度为50,那么执行完这次任务,需要轮询两次才能完成,如果并行度为100,那么一次就可以了。

但是在资源相同的情况,并行度高了,相应的Executor内存就会减少,所以需要根据实际实况协调内存和core。此外,Spark能够非常有效的支持短时间任务(例如:200ms),因为会对所有的任务复用JVM,这样能减小任务启动的消耗,Standalone模式下,core可以允许1-2倍于物理core的数量进行超配。

【Spark任务数量调整】

Spark的任务数由stage中的起始的所有RDD的partition之和数量决定,所以需要了解每个RDD的partition的计算方法。以Spark应用从HDFS读取数据为例,HadoopRDD的partition切分方法完全继承于MapReduce中的FileInputFormat,具体的partition数量由HDFS的块大小、mapred.min.split.size的大小、文件的压缩方式等多个因素决定,详情需要参见FileInputFormat的代码。

【Spark内存调优】

内存优化有三个方面的考虑:对象所占用的内存,访问对象的消耗以及垃圾回收所占用的开销。

1. 对象所占内存,优化数据结构

Spark 默认使用Java序列化对象,虽然Java对象的访问速度更快,但其占用的空间通常比其内部的属性数据大2-5倍。为了减少内存的使用,减少Java序列化后的额外开销,下面列举一些Spark官网(http://spark.apache.org/docs/latest/tuning.html#tuning-data-structures)提供的方法。

(1)使用对象数组以及原始类型(primitive type)数组以替代Java或者Scala集合类(collection class)。fastutil 库为原始数据类型提供了非常方便的集合类,且兼容Java标准类库。

(2)尽可能地避免采用含有指针的嵌套数据结构来保存小对象。

(3)考虑采用数字ID或者枚举类型以便替代String类型的主键。

(4)如果内存少于32GB,设置JVM参数-XX:+UseCom-pressedOops以便将8字节指针修改成4字节。与此同时,在Java 7或者更高版本,设置JVM参数-XX:+UseC-----ompressedStrings以便采用8比特来编码每一个ASCII字符。

2. 内存回收

(1)获取内存统计信息:优化内存前需要了解集群的内存回收频率、内存回收耗费时间等信息,可以在spark-env.sh中设置SPARK_JAVA_OPTS=“-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps $ SPARK_JAVA_OPTS”来获取每一次内存回收的信息。

(2)优化缓存大小:默认情况Spark采用运行内存(spark.executor.memory)的60%来进行RDD缓存。这表明在任务执行期间,有40%的内存可以用来进行对象创建。如果任务运行速度变慢且JVM频繁进行内存回收,或者内存空间不足,那么降低缓存大小设置可以减少内存消耗,可以降低spark.storage.memoryFraction的大小。

3. 频繁GC或者OOM

针对这种情况,首先要确定现象是发生在Driver端还是在Executor端,然后在分别处理。

Driver端:通常由于计算过大的结果集被回收到Driver端导致,需要调大Driver端的内存解决,或者进一步减少结果集的数量。

Executor端:

(1)以外部数据作为输入的Stage:这类Stage中出现GC通常是因为在Map侧进行map-side-combine时,由于group过多引起的。解决方法可以增加partition的数量(即task的数量)来减少每个task要处理的数据,来减少GC的可能性。

(2)以shuffle作为输入的Stage:这类Stage中出现GC的通常原因也是和shuffle有关,常见原因是某一个或多个group的数据过多,也就是所谓的数据倾斜,最简单的办法就是增加shuffle的task数量,比如在SparkSQL中设置SET spark.sql.shuffle.partitions=400,如果调大shuffle的task无法解决问题,说明你的数据倾斜很严重,某一个group的数据远远大于其他的group,需要你在业务逻辑上进行调整,预先针对较大的group做单独处理。

【修改序列化】

使用Kryo序列化,因为Kryo序列化结果比Java标准序列化更小,更快速。具体方法:spark-default.conf 里设置spark.serializer为org.apache.spark.serializer.KryoSerializer 。

参考官方文档(http://spark.apache.org/docs/latest/tuning.html#summary):对于大多数程序而言,采用Kryo框架以及序列化能够解决性能相关的大部分问题。

【Spark 磁盘调优】

在集群环境下,如果数据分布不均匀,造成节点间任务分布不均匀,也会导致节点间源数据不必要的网络传输,从而大大影响系统性能,那么对于磁盘调优最好先将数据资源分布均匀。除此之外,还可以对源数据做一定的处理:

1. 在内存允许范围内,将频繁访问的文件或数据置于内存中;

2. 如果磁盘充裕,可以适当增加源数据在HDFS上的备份数以减少网络传输;

3. Spark支持多种文件格式及压缩方式,根据不同的应用环境进行合理的选择。如果每次计算只需要其中的某几列,可以使用列式文件格式,以减少磁盘I/O,常用的列式有parquet、rcfile。如果文件过大,将原文件压缩可以减少磁盘I/O,例如:gzip、snappy、lzo。

【其他】

广播变量(broadcast)

当task中需要访问一个Driver端较大的数据时,可以通过使用SparkContext的广播变量来减小每一个任务的大小以及在集群中启动作业的消耗。参考官方文档http://spark.apache.org/docs/latest/tuning.html#broadcasting-large-variables。

开启推测机制

推测机制后,如果集群中,某一台机器的几个task特别慢,推测机制会将任务分配到其他机器执行,最后Spark会选取最快的作为最终结果。

在spark-default.conf 中添加:spark.speculation true

推测机制与以下几个参数有关:

1. spark.speculation.interval 100:检测周期,单位毫秒;

2. spark.speculation.quantile 0.75:完成task的百分比时启动推测;

3. spark.speculation.multiplier 1.5:比其他的慢多少倍时启动推测。

总结

Spark系统的性能调优是一个很复杂的过程,需要对Spark以及Hadoop有足够的知识储备。从业务应用平台(Spark)、存储(HDFS)、操作系统、硬件等多个层面都会对性能产生很大的影响。借助于多种性能监控工具,我们可以很好地了解系统的性能表现,并根据上面介绍的经验进行调整。

   
2370 次浏览       50
 
相关文章

云计算的架构
对云计算服务模型
云计算核心技术剖析
了解云计算的漏洞
 
相关文档

云计算简介
云计算简介与云安全
下一代网络计算--云计算
软浅析云计算
 
相关课程

云计算原理与应用
云计算应用与开发
CMMI体系与实践
基于CMMI标准的软件质量保证
最新课程计划

专家视角看IT与架构
软件架构设计
面向服务体系架构和业务组件的思考
人人网移动开发架构
架构腐化之谜
谈平台即服务PaaS
更多...   
相关培训课程

云计算原理与应用
Windows Azure 云计算应用

摩托罗拉 云平台的构建与应用
通用公司GE Docker原理与实践
某研发中心 Openstack实践
知名电子公司 云平台架构与应用
某电力行业 基于云平台构建云服务
云计算与Windows Azure培训
北京 云计算原理与应用