spark源码阅读——6. 性能优化

spark性能优化

 

1.数据序列化(serializer)

spark提供两种序列化方式,一种是java序列化,另一种是Kryo序列化

java序列化比较灵活,但速度较慢,为了方便,spark默认使用java,可以更改为Kryo

对于大多数程序而言,Kryo序列化可以解决有关性能的大部分问题

Kryo序列化机制的优点:

(1)算子函数中使用的外部变量,在经过kryo序列化之后,会优化网络传输的性能,优化集群中内存的占用和消耗

(2)持久化RDD时进行序列化,保存为byte类型,StorageLevel.MEMORY_ONLY_SER,优化内存的占用和消耗

(3)在shuffle 方面优化网络传输的性能

步骤:

(1) 在SparkConf中设置一个属性

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

(2)注册需要使用Kryo序列化的自定义的类

如果要达到Kryo的最佳性能的话,那么就一定要注册自定义的类

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

.registerKryoClasses(new Class[]{CategorySortKey.class})

 

2.内存优化

如果没设置数据序列化,也可以单独设置RDD存储序列化,把RDD保存为byte类型,即设置RDD的持久化级别为MEMORY_ONLY_SER

rdd1.persist(StorageLevel.MEMORY_ONLY_SER)

其它:优化数据结构、内存回收

 

3.并行度优化

并行度最好跟cpu的核数(core)一致

理想情况下,task数量设置成Spark Application 的总CPU核数,但是现实中总有一些task运行慢一些task快,导致快的先执行完,空余的cpu 核就浪费掉了,所以官方推荐task数量要设置成Spark Application的总cpu核数的2~3 倍

val conf = new SparkConf().set("spark.default.parallelism", "4")

 

4.广播大变量

spark的broadcast可以有效地减少通信的消耗,对于比较大的对象,可以广播出去,一般来说,大于20kb的对象都是值得优化的。

val broadcastVar = sc.broadcast(Array(1, 2, 3))

 

5.数据本地性

可以增加数据本地化的等待时长,增加spark.locality.wait,默认是3s

对于Application的每一个task,Spark在进行分配之前,都会计算出这个task要处理的数据在哪个分片,(partition).Spark的task分配算法希望每个task都正好分配到它要计算的数据所在的节点上,这样就避免了网络间传输数据 。比如要处理的数据在slave1节点,spark就希望计算这块数据的task也在这个节点上。

但是,task可能没有机会分配到它的数据所在的节点,因为可能计算资源和计算能力都满了,这种情况下,Spark会等待一段时间,过了这个时间,才会选择一个比较差的本地化级别,比如将这个task分配到相邻的一个节点上,这个时候肯定发生网络传输,会通过一个getRemote()方法,通过TransferService(网络数据传输组件)从数据所在节点的BlockManager中获取数据。

 

分级,按照当前数据和task的距离来分级,由近到远分为:

PROCESS_LOCAL:进程本地化,代码和数据在同一个进程中,也就是在同一个executor中;计算数据的task由executor执行,数据在executor的BlockManager中;性能最好

NODE_LOCAL:节点本地化,代码和数据在同一个节点中;比如说,数据作为一个HDFSblock块,就在节点上,而task在节点上某个executor中运行;或者是,数据和task在一个节点上的不同executor中;数据需要在进程间进行传输

NO_PREF:对于task来说,数据从哪里获取都一样,没有好坏之分

RACK_LOCAL:机架本地化,数据和task在一个机架的两个节点上;数据需要通过网络在节点之间进行传输

ANY:数据和task可能在集群中的任何地方,而且不在一个机架中,性能最差

 

如果大多都是PROCESS_LOCAL,那就不用调节了

如果是发现,好多的级别都是NODE_LOCAL、ANY,那么最好就去调节一下数据本地化的等待时长

调节完,应该是要反复调节,每次调节完以后,再来运行,观察日志

看看大部分的task的本地化级别有没有提升;看看,整个spark作业的运行时间有没有缩短

 

调节方法:

spark.locality.wait,默认是3s;可以调节为6s,10s

new SparkConf().set("spark.locality.wait", "10")

 

默认情况下,下面3个的等待时长,都是跟上面那个是一样的,都是3s

spark.locality.wait.process

spark.locality.wait.node

spark.locality.wait.rack

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值