最具影响力的数字化技术在线社区

168大数据

 找回密码
 立即注册

QQ登录

只需一步,快速开始

1 2 3 4 5
打印 上一主题 下一主题
开启左侧

Spark性能优化第四季

[复制链接]
跳转到指定楼层
楼主
发表于 2017-7-4 15:18:21 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

马上注册,结交更多数据大咖,获取更多知识干货,轻松玩转大数据

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
一:Spark性能调优之序列化
1,之所以进行序列化,最重要的原因是内存空间有限(减少GC的压力,最大化的避免Full GC的产生,因为一旦产生Full GC则整个Task处于停止状态!!!)、减少磁盘IO的压力、减少网络IO的压力;
2,什么时候会必要的产生序列化或反序列化呢?发生磁盘IO和网络通讯的时候会序列化和反序列化,更为重要的考虑序列化和反序列化的时候有另外两种情况:
A)Persist(Checkpoint)的时候必须考虑序列化和反序列化,例如说cache到内存的时候只能使用JVM分配的60%的内存空间,此时好的序列化机制就至关重要了
B)编程的时候!使用算子的函数操作如果传入了外部数据就必须序列化和反序列化;
conf.set(“spark.serializer”, “org.apache.spark.serializer.KryoSerializer”)
conf.registerKryoClasses(Array(classOf[Person]))
val person = new Person()
Rdd.map(item => person.add(item))
3,强烈建议使用Kryo序列器进行序列化和反序列化;Spark默认情况下不是使用Kryo而是Java自带的序列化器ObjectIntputStream和ObjectOutputStream(主要是考虑了方便性或者是通用性),如果自定义了RDD中数据元素的类型则必须实现Serializable接口,当然你也可以实现自己的序列化接口Externalizable来实现更加高效的Java序列化算法;采用默认的ObjectIntputStream和ObjectOutputStream会导致序列化后的数据占用大量的内存或者磁盘或者大量的消耗网络,并且在序列化和反序列化的时候比较消耗CPU;
4,强烈推荐大家采用Kryo序列化机制,Spark下使用Kryo序列化机制会比Java默认的序列化机制更加节省空间(减少近10倍的空间)以及更少的消耗CPU,个人强烈建议大家在一切情况下尽可能的使用Kryo序列化机制!
5,使用Kryo的两种方式:
A)在spark-defults.conf中配置,例如:
spark.serializer org.apache.spark.serializer.KryoSerializer
B)在程序的SparkConf中配置,例如:
conf.set(“spark.serializer”, “org.apache.spark.serializer.KryoSerializer”)
Ps:使用Kryo可以更加快速,更低存储空间占用量以及更高性能的方式进行序列化
6,Spark中Scala常用的类型自动的通过AllScalaRegistrar注册给Kryo进行序列化管理;
7,如果是自定义的类型必须注册给序列化器,例如:
conf.set(“spark.serializer”, “org.apache.spark.serializer.KryoSerializer”)
conf.registerKryoClasses(Array(classOf[Person]))
val person = new Person()
rdd.map(item => person.add(item))
Ps:另一种方式是Person实现Serializable接口。
8,Kryo在序列化的时候缓存空间默认大对象是2MB,可以更具体的业务模型调整改变大小,具体方式:设置spark.kyroserializer.buffer为10MB等;
9,在使用Kyro强烈建议注册时写完整的包名和类名,否则的话每次序列化的时候都会保存一份整个包名和类名的完整信息,这就减少不必要的消耗内存空间;
二:Spark JVM性能调优

1,好消息是Spark的钨丝计划是用来专门解决JVM性能问题的,不好的消息是至少在Spark 2.0以前钨丝计划功能不稳定并且不完善只能在特定的情况下发生作用,也就是说包括Spark 1.6在内的Spark及其以前的版本我们大多数情况下没有使用钨丝计划的功能,所以此时就必须关注JVM性能调优;
2,JVM性能调优的关键是调优GC!!!,为什么GC如此重要?主要是因为Saprk热衷于RDD的持久化!!!GC本身的性能开销是和数据量成正比的;
3,初步可以考虑是尽量多的使用Array和String,并且在序列化机制方面尽可能的Kyro,让每个partition都成为字节数组;
4,监视GC的基本方式有两种:
A)配置
spark.executor.extraJavaOptions=-verbose:gc -XX:+PrintGCDetails -XX:+ PrintGCDateTimeStamps
B)SparkUI
5,Spark在默认情况下使用60%的空间来进行Cache缓存RDD的内容,也就是说Task在执行的时候只能使用剩下的40%;如果空间不够用就会触发(频繁的)GC
可以设置spark.memory.fraction参数来进行调整空间的使用,例如降低Cache的空间,让Task使用更多的空间来创建对象和计算;
再一次,强烈建议进行RDD从Cache的时候使用Kyro序列化机制,从而给Task可以分配更大的空间来顺利完成计算(避免频繁的GC)
6,因为在老年代空间满的时候会发送FullGC操作,而老年代空间中基本是活的比较久的对象(经历数次GC依旧存在),此时会停下所有程序线程,进行Full GC,对老年代中的对象进行整理,严重影响性能;此时可以考虑:
A) 可以设置spark.memory.fraction参数来进行调整空间的使用来给年轻代更多的空间用于存放短时间的存活的对象;
B) -Xmn调整Eden区域;对RDD中操作的对象和数据进行大小评估,如果在HDFS上解压后一般体积可能会变成原有体积的3倍左右;根据数据的大小设置Eden;如果有10个Task,每个Task处理的HDFS上的数据是128M,则需要设置Xmn为10*128*3*4/3的大小;
C) -XX:SupervisorRatio;
D) -XX:NewRatio;

楼主热帖
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 转播转播 分享分享 分享淘帖 赞 踩

168大数据 - 论坛版权1.本主题所有言论和图片纯属网友个人见解,与本站立场无关
2.本站所有主题由网友自行投稿发布。若为首发或独家,该帖子作者与168大数据享有帖子相关版权。
3.其他单位或个人使用、转载或引用本文时必须同时征得该帖子作者和168大数据的同意,并添加本文出处。
4.本站所收集的部分公开资料来源于网络,转载目的在于传递价值及用于交流学习,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。
5.任何通过此网页连接而得到的资讯、产品及服务,本站概不负责,亦不负任何法律责任。
6.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源,若标注有误或遗漏而侵犯到任何版权问题,请尽快告知,本站将及时删除。
7.168大数据管理员和版主有权不事先通知发贴者而删除本文。

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

关于我们|小黑屋|Archiver|168大数据 ( 京ICP备14035423号|申请友情链接

GMT+8, 2024-6-4 00:53

Powered by BI168大数据社区

© 2012-2014 168大数据

快速回复 返回顶部 返回列表