Spark调优解决方案(二)之并行度调节以及RDD架构重用与持久化

一、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()        如果内存非常充足,考虑高可用,选择此项

















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值