spark优化点

在spark优化hadoop中的思路,就是优化了hadoop的shuffle过程。shuffle落入磁盘,需要将数据序列化。spark已经将shuffle过程优化,在此基础上进一步优化,需要对序列化进行优化

一、序列化优化:

spark用到序列化的地方

1、shuffle时需要将对象写入到外部的临时文件
2、每个partition的数据要发送给worker,spark先把RDD包装成task对象,将task序列化,通过网络发送给woker
3、RDD过大时,会写入到硬盘,涉及到序列化

spark默认序列化

spark默认序列化用的是java序列化。
java序列化有两个问题:
一、是性能相对较低
二、序列化的二进制的内容长度较大,造成网络传输时间长

更优秀的序列化框架kryo

官网:https://github.com/EsotericSoftware/kryo
介绍:
Kryo is a fast and efficient binary object graph serialization framework for Java. The goals of the project are high speed, low size, and an easy to use API. The project is useful any time objects need to be persisted, whether to a file, database, or over the network.

相比于java,kryo序列化速度快,占用空间小。

让spark使用kryo序列化

方法一:修改spark-defaults.conf配置文件
设置:
spark.serializer org.apache.spark.serializer.KryoSerializer

方法二:启动spark-shell或者spark-submit时配置
--conf spark.serializer=org.apache.spark.serializer.KryoSerializer

方法三:在代码中
val conf = new SparkConf()
conf.set(“spark.serializer”,“org.apache.spark.serializer.KryoSerializer”)

二、减少原始数据

少用包装类,多用基础类
包装类比基础类多了许多的类信息,方法信息等

三、经常发生fullGC就要减少缓存的大小

缓存一直占有着老生代,它不会轻易的被清除。缓存越来愈多,占用的内存就会越来越多。而saprk是基于内存的
计算框架,内存小会导致数据落入磁盘,影响效率,因此,要将spark缓存的内容设置小。
官网调优地址:http://spark.apache.org/docs/latest/tuning.html#serialized-rdd-storage

spark.memory.storageFraction expresses the size of R as a fraction of M (default 0.5). R is the storage space within M where cached blocks immune to being evicted by execution.

最新版本已经默认将缓存大小设置为0.5

四、RDD调优

spark.storage.memoryFraction如果很多rdd对象经常要重复使用,这时可以spark.storage.memoryFraction调大,如果没有什么需要重用的rdd需要缓存,可以把这个调小,把更多的内存留给计算使用。
序列化RDD存储
rdd.persist(StorageLevel.MEMORY_ONLY)		//只对缓存数据序列化
rdd.persist(StorageLevel.MEMORY_ONLY_SER)	//对其中的对象做序列化
序列化后对象占用的内存就减少了,可以容纳更多的数据,另外占用内存减少,减少fullGC垃圾回收

五、并行度调优

RDD数据量超过内存大小,中间结果会保存在硬盘,效率降低。此时可把并行度调大,这就意味着每个任务占的内存变小,同时容纳的任务数增多。
例如:每个任务需要500M的内存,但内存只有400M。
之前按4个分区sc.repartition(),4*500M=2G,一个分区需要500M算,需要2G。加大并发量,变成5个分区,每个分区400M,这样5*400M=2G。这样内存就够用了。

六、数据本地化

尽量让worker节点和hadoop的dataNode在同一台服务器上,那就不用跨网络访问.
内部由hadoop的api来具体实现。可以配置机架等。
访问速度:远程 < 局域网 < 机架 < 本机

七、空任务、小任务合并

如果多次filter操作后会产生多个空任务和小任务,partition数据量没了,或者非常小,再由RDD包装成一个task,降低效率。此时应用coalesce和repartition合并,空的过滤,小的合并,减少了一些不必要的任务执行。

八、配置临时文件记录

spark.local.dir参数。当shuffle、归并排序(sort、merge)时都会产生临时文件。这些临时文件都在此指定目录下。那这个文件夹有很多临时文件,发生读写操作时,有的线程在读此文件,有的线程在写此文件,IO性能就非常低。
可以创建多个文件夹,每个文件夹都对应一个真实的硬盘。假如原来是3个程序同时读写一个硬盘,效率肯定低,现在让三个程序分别读取3个磁盘,冲突减少,效率提高。
配置:
只需要在这个配置时配置多个路径就可以。中间用逗号分隔。
spark.local.dir=目录1,目录2,目录3

九、woker倾斜

有时,一个worker分配的任务很多,其他worker却没有工作或者很快能执行完,导致所有worker别的都在等最慢的,这种情况叫做worker的倾斜。
woker倾斜的原因是数据分配不合理,即key划分的不合理。此时需观察key的分布,如果发现这种数据倾斜,就重新定义key,找到一个合适的key的算法。

十、reducer数量不合适

当做reduceByKey、groupByKey时,partition的数量就是reduce的数量,这个数量也需要根据实际情况调整,太多的reducer就造成task很小。看着任务多了,但任务不饱满,还不如较少的reducer的性能高。但如果reducer太少,并发数就不够,任务执行就慢。
所以要根据实际情况来调优reducer数量。

十一、RDD操作使用MapPartition替代Map

map方法对RDD的每一条记录逐一操作。mapPartition是对整个RDD,以迭代器的方式逐一操作,如下面代码
rdd map x=>conn=getDBConn.conn;write(x.toString);conn close;
这样频繁的链接、断开数据库,效率差。
rdd mapPartitions(record:=>conn.getDBConn;for(item<-recorders;write(item.toString);conn close;
这样就一次链接一次断开,中间批量操作,效率提升。

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spark SQL 优化主要包括逻辑优化、物理优化以及执行优化等方面。首先,在逻辑优化方面,可以使用谓词下推、投影消除以及JOIN重排等技术来降低数据的处理量。通过谓词下推,可以将过滤条件下推到数据源,减少不必要的数据读取;通过投影消除,可以消除不必要的列读取,进一步减少数据处理量;通过JOIN重排,可以改变JOIN的顺序,使之能够更高效地执行。 其次,在物理优化方面,可以通过数据倾斜处理、分区表以及压缩等技术来提高性能。通过数据倾斜处理,可以解决某些数据分布不均衡的情况,提高任务的并行度;通过分区表,可以将数据按照某个字段进行划分,提高查询的效率;通过压缩,可以减少数据的存储间,从而减少IO开销。 最后,在执行优化方面,可以通过内存管理、并行执行以及向量化等技术来提高执行效率。通过合理管理内存,避免OOM等问题,提高任务的稳定性;通过并行执行,将多个任务并行执行,加快任务的完成速度;通过向量化,将一批数据作为一个向量进行计算,提高计算的效率。 总结来说,Spark SQL 优化主要包括逻辑优化、物理优化以及执行优化等方面的技术手段,通过合理应用这些技术,可以提高Spark SQL 的执行效率,减少数据处理量,提高查询性能,从而更高效地完成数据处理任务。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值