Spark性能优化第一步,应用一些性能优化的基本原则。开发调优包括:RDD lineage设计,算子的合理使用,特殊操作的优化等.并将这些原则根据具体的业务以及实际的应用场景,灵活地应用到Spark作业中.
###原则一:避免创建重复的RDD
通常来说,开发Spark作业,首先基于某个数据源(hive表或hdfs文件)创建一个初始的RDD,接着对这个RDD执行某个算子操作,然后得到下一个RDD,反复循环得到最终结果。在这个过程中,多个RDD通过不同算子操作串起来,就是RDD lineage,也就是"RDD的血缘关系链"。
开发过程中要注意:对同一份数据,只创建一个RDD.(避免同一份数据下多个RDD带来的多余性能开销)
###原则二:尽可能复用同一个RDD
在不同数据执行算子操作时还要尽可能的复用同一个RDD,比如一个算子使用key-valu,另一算子是单value类型,这两个RDD使用的是相同的value这种情况下,复用同一个RDD,这样减少RDD数量和算子执行次数。
###原则三:对多次使用的RDD进行持久化操作
因为多次复用的RDD,都会从源头处计算.通过持久化操作将RDD存入内存或磁盘中,对复用的RDD直接从内存中提取使用避免重复源头计算。spark持久化persist()方法,有不同的策略级别
###原则四:尽量避免使用shuffle类算子
如果有可能尽可能避免shuffle过程(最消耗性能的地方就是shuffle),shuffle过程简单的说,就是将不同节点相同的key,拉取到同一个节点中做聚合等操作。这中间涉及到溢写,大量磁盘IO过程(shuffle性能较差的主要原因).因此在开发中,尽量避免使用shuffle类算子。
###原则五:使用高性能的算子
使用reduceByKye/aggregateByKey替代groupByKey,使用map-side预聚合的shuffle操作。
使用mapPartitions替代普通的map
使用foreachPartitions替代foreachs
使用filter之后进行coalesce,减少partition数量
使用repartitionAndSortWithinPartition替代repartition与sort操作
###原则六:广播大变量
通过使用广播变量将(100M ~ 1G)数据集在每个executor中保留一个副本,通过本地保留来减少网络传输的开销。
###原则七:使用Kryo优化序列化性能
通过使用Kryo序列化机制而避免使用Java序列化机制,对性能进行提高。