一、Spark并行度指的是什么?
-------------------------------------------------------
1.首先先解释下Spark作业的阶段划分
一个spark作业可以理解成一个application, 一个Application是由jobs组成
job的划分是根据Action算子来的,每个Action之前的操作合计为一个job
每个job分为多个stage
stage的划分是通过发生shuffle的算子来的,每个shuffle算子之前的操作合计为一个stage
每个stage分为多个task
每个rdd的操作都是若干个task
Excutor进程会为每个task分配一个单独的线程去执行task
2.shuffle阶段发生了什么?
stage是通过shuffle算子进行划分的,比如stage0和stage1
其实发生shuffle算子是跨越这2个stage的
上一个阶段stage0,会为stage1 准备对应的文件,里面存放着key,value信息,比如reduceByKey
然后进行shuffle,会对key进行分组操作,保证相同的key一定会进入同一个文件中,但是一个文件可以有多个key以及其对应的values
3.并行度其实就是同时执行的task的数量
其实就是指的是,Spark作业中,各个stage的task数量,也就代表了Spark作业的在各个阶段(stage)的并行度。
4.合理设置并行度的好处?
合理设置并行度,其实就是设置成足够大,大到可以合理的利用资源。
例如,50个excutor,每个excutor有3个core,那么就总共有150个core.那么你的并行度至少也是150(或者150的倍数)
并行度增加了,那么同时执行的task增加了,最终结果就是提升你的整个Spark作业的性能和运行速度。
二、如何设置并行度?
----------------------------------------------
1.最小设置:至少设置成与Spark application的总cpu core数量相同
2.推荐设置:设置成spark application总cpu core数量的2~3倍,比如150个cpu core,基本要设置task数量为300~500;
实际情况,与理想情况不同的,有些task会运行的快一点,比如50s就完了,有些task,可能会慢一点,要1分半才运行完,
所以如果你的task数量,刚好设置的跟cpu core数量相同,可能还是会导致资源的浪费,
因为,比如150个task,10个先运行完了,剩余140个还在运行,但是这个时候,有10个cpu core就空闲出来了,
就导致了浪费。那如果task数量设置成cpu core总数的2~3倍,那么一个task运行完了以后,
另一个task马上可以补上来,就尽量让cpu core不要空闲,同时也是尽量提升spark作业运行的效率和速度,提升性能。
3.如何设置一个Spark Application的并行度?
设置spark.default.parallelism
SparkConf conf = new SparkConf().set("spark.default.parallelism", "500")
三、RDD架构重用与持久化
--------------------------------------------
1.尽量去复用RDD,内容差不多的RDD尽量抽取出来一个公共的RDD,供后面反复使用
2.公共的RDD一定要持久化
持久化,就是将RDD的数据缓存到内存中/磁盘中,(BlockManager),以后无论对这个RDD做多少次计算,
那么都是直接取这个RDD的持久化的数据,比如从内存中或者磁盘中,直接提取一份数据。
3.尽量选择序列化的方式去持久化RDD,以减少内存开销
序列化的优势,大大减小内存开销。缺点,使用的时候需要反序列化
如果序列化到内存的方式还是导致内存溢出,那么就将溢出的部分持久化到磁盘中(此时,可以选择序列化和非序列化)
4.为了数据的高可用,而且内存足够充,可以采用双副本机制,进行持久化
双内存副本机制是为了避免,当系统宕机了,内存中持久化的数据就丢失了
为了避免这种情况,可以在其他节点上创建一个持久化的副本,一个副本丢了,不用重新计算,直接使用副本即可
当然,这种情况仅仅针对于内存足够的情况
5.持久化使用的是BlockManager
6.如何持久化?
//持久化sessionid2actionRDD
sessionid2actionRDD = sessionid2actionRDD.persist(StorageLevel.MEMORY_ONLY());
首选级别:
a.StorageLevel.MEMORY_ONLY() 仅内存,非序列化,相当于cache()
b.StorageLevel.MEMORY_ONLY_SER() 仅内存, 序列化
c.StorageLevel.MEMORY_AND_DISK() 内存和磁盘,非序列化
d.StorageLevel.MEMORY_AND_DISK_SER() 内存和磁盘, 序列化
e.StorageLevel.DISK_ONLY() 仅磁盘
f.StorageLevel.MEMORY_ONLY_SER() 如果内存非常充足,考虑高可用,选择此项
Spark调优解决方案(二)之并行度调节以及RDD架构重用与持久化
最新推荐文章于 2022-08-07 19:37:31 发布