Tuning Spark

Data Serialization

数据序列化,对于任意分布式系统都是性能的关键点

Spark默认使用Java serialization,这个比较低效

推荐使用,Kryo serialization,会比Java序列化,更快更小, Spark使用Twitter chill library(Kryo的scala扩展)

conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")

conf.set("spark.kryoserializer.buffer.mb“, 2), 需要大于最大的需要序列化的对象size

之所以,spark不默认使用Kryo,因为Kryo需要显式的注册program中使用到的class,参考

val conf = new SparkConf().setMaster(...).setAppName(...)
conf.registerKryoClasses(Array(classOf[MyClass1], classOf[MyClass2]))
val sc = new SparkContext(conf)

只所以要做注册是因为,在把对象序列化成byte[]时,要记录下classname,classname带namespace一般很长的,所以每个里面加上这个classname比较费空间
在kryo里面注册过后,会用一个int来替代classname
当然不注册kryo也是可以用的,只是会多占空间

 

Memory Tuning

Tuning之前需要知道当前dataset的内存消耗是多少,
简单的方法是,以该dataset创建rdd,然后cache
这样从SparkContext的日志里面可以看到每个partition的大小,加一下,就可以得到整个数据集的大小

INFO BlockManagerMasterActor: Added rdd_0_1 in memory on mbk.local:50311 (size: 717.5 KB, free: 332.3 MB)
This means that partition 1 of RDD 0 consumed 717.5 KB.
然后可以从几个方面去进行优化,

Tuning Data Structures

Java对象虽然便于访问,但是和raw data比,java对象的size要大2~5倍
Each distinct Java object has an “object header”, which is about 16 bytes
Java Strings have about 40 bytes of overhead over the raw string data, and store each character as two bytes due to String’s internal usage of UTF-16 encoding
其他的比如HashMap或LinkedList,除了header,还需要8 bytes pointer来指向下个对象
总之,就是对于内存敏感的应用,直接使用Java对象是非常不经济的
可以从以下几点去优化,
a, 优先使用arrays of objects, and primitive types,而非java或scala的标准collection class
或者使用fastutil library,这个库提供了用primitive types实现的collection class
b, 避免含有大量小对象或pointer的嵌套数据结构
c, Consider using numeric IDs or enumeration objects instead of strings for keys
d, If you have less than 32 GB of RAM, set the JVM flag -XX:+UseCompressedOops to make pointers be four bytes instead of eight. You can add these options in spark-env.sh.

Serialized RDD Storage

使用MEMORY_ONLY_SER,在memory中cache序列化后的数据,降低内存使用,当然响应的访问速度会降低,由于需要反序列化

Garbage Collection Tuning

首先需要打开gc日志,
adding -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps to the Java options

Cache Size Tuning
默认Spark使用60% 的executor memory(spark.executor.memory)来cache RDDs.
也就是说只有40%的memory用于task执行,如果发现频繁gc或是oom,可以调低用于cache的比例,
conf.set("spark.storage.memoryFraction", "0.5"), 这样设成50%
Advanced GC Tuning
Spark做gc tuning的目标是,避免在task执行过程中发生full gc, 即需要让Young区足够容纳short-lived objects
a, 如果发生多次full gc或是OldGen已经接近full,说明内存不够,可以降低cache比例
b, 如果很多minor gc,但没有major gc,说明young区过小, 我们可以根据task dataset需要消耗内存来预估eden区,young区大小= eden区 × (4/3),因为要加上survivor区
c, 如果从hdfs读取数据,可以根据hdfs block大小来预估eden区大小,比如,如果解压比例3倍,4个tasks并行,block大小64M,那么eden区大小 = 3×4×64M
 

其他的一些考虑,

调整并发的level, 通过增加并发来降低reduce task的内存消耗

broadcast functionality来处理大的变量, data locality


本文章摘自博客园,原文发布日期:2015-04-21

优秀的个人博客,低调大师

微信关注我们

原文链接:https://yq.aliyun.com/articles/86088

转载内容版权归作者及来源网站所有!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
Mario,低调大师唯一一个Java游戏作品

Mario,低调大师唯一一个Java游戏作品

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Apache Tomcat7、8、9(Java Web服务器)

Apache Tomcat7、8、9(Java Web服务器)

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Eclipse(集成开发环境)

Eclipse(集成开发环境)

Eclipse 是一个开放源代码的、基于Java的可扩展开发平台。就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境。幸运的是,Eclipse 附带了一个标准的插件集,包括Java开发工具(Java Development Kit,JDK)。

Java Development Kit(Java开发工具)

Java Development Kit(Java开发工具)

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。