Spark 性能相关参数配置详解

Spark 性能相关参数配置详解

*压缩与序列化篇*
        spark.serializer -> 选取序列化器
            默认为org.apache.spark.serializer.JavaSerializer -> 可选org.apache.spark.serializer.KryoSerializer
                => 这里可配的Serializer针对的对象是Shuffle数据,以及RDD Cache等场合
                => Spark Task的序列化是通过spark.closure.serializer来配置,但是目前只支持JavaSerializer
        spark.broadcast.compress --是否对Broadcast数据进行压缩
            对Broadcast的数据进行压缩,默认值为True
            Broadcast机制是用来减少运行每个Task时,一个Executor只需要在第一个Task启动时,获得一份Broadcast数据,之后的Task都从本地的BlockManager中获取相关数据.
            1.1中,RDD本身也改为以Broadcast的形式发送给Executor(之前的实现RDD本身是随每个任务发送的)
            什么情况可能不压缩更好呢,在网络带宽和内存不是问题,且Driver端CPU资源很成问题(毕竟压缩的动作基本都在Driver端执行),那或许有调整的必要。
        spark.rdd.compress --> rdd 序列化后,是否再压缩
            RDD Cache的过程中,RDD数据在序列化之后是否进一步进行压缩再储存到内存或磁盘上.
            对于Cache在磁盘上而言,绝对大小大概没有太大关系,主要是考虑Disk的IO带宽
            而对于Cache在内存中,那主要就是考虑尺寸的影响,是否能够Cache更多的数据,是否能减小Cache数据对GC造成的压力
            这个值默认是关闭的
            如果在磁盘IO的确成为问题或者GC问题真的没有其它更好的解决办法的时候,可以考虑启用RDD压缩。
        spark.io.compression.codec  --> 如果压缩的话,采用什么压缩算法.
            RDD Cache和Shuffle数据压缩所采用的算法Codec,曾经是使用LZF作为默认Codec,最近因为LZF的内存和CPU开销的问题,默认的Codec已经改为Snappy.
            Shuffle
                使用HashShuffleManager时可能成为问题,因为如果Reduce分区数量巨大,需要同时打开大量的压缩数据流用于写文件.
                使用SortShuffleManager,由于shuffle文件数量大大减少,不会产生大量的压缩数据流,所以内存开销大概不会成为主要问题。
                个人认为CPU通常更容易成为瓶颈,所以要调整性能,要不不压缩,要不使用Snappy可能性大一些!

*Shuffle 相关*
    Shuffle操作大概是对Spark性能影响最大的步骤之一(因为可能涉及到排序,磁盘IO,网络IO等众多CPU或IO密集的操作),所以在 1.1进行了重构。
        spark.shuffle.manager 
            HashShuffleManager
                问题:如果Reduce分区的数量比较大,将会产生大量的磁盘文件.此外由于同时打开的文件句柄数量众多,序列化,压缩,对内存的使用和GC带来很大的压力.
            SortShuffleManager(default)
                同一个Map任务Shuffle到不同的Reduce分区中去的所有数据都可以写入到同一个外部磁盘文件,用Offset标志不同Reduce分区的偏移量
             ->选择
                如果不需要sort的shuffle,如果文件数量不是特别巨大,HashShuffleManager面临的内存问题不大。而SortShuffleManager需要额外的根据Partition进行排序。
                如果本来就需要在Map端进行排序的Shuffle,SortShuffleManager
        spark.shuffle.sort.bypassMergeThreshold
            仅限于 SortShuffleManager,小于设置数,不使用Merge Sort的方式处理数据,与Hash Shuffle类似,直接将分区文件写入单独的文件,最后合并文件,本质上是相对HashShuffleMananger一个折衷方案.
        spark.shuffle.consolidateFiles
            仅适于HashShuffleMananger,为了解决生成过多文件的问题.涉及到底层具体的文件系统的实现和限制等因素,一直有bug.
        spark.shuffle.spill
            默认打开
            内存不够用怎么办,一out of memory 出错了,
                                二就是将部分数据临时写到外部存储设备中去,最后再合并到最终的Shuffle输出文件中去
        spark.shuffle.memoryFraction / spark.shuffle.safetyFraction
            前者(1.1后默认为0.2)决定了当Shuffle过程中使用的内存达到总内存多少比例的时候开始Spill
            由于Shuffle数据的大小是估算出来的.
            后者是到了这个阀值,一定要spill,要不然就悲剧了。
        spark.shuffle.spill.compress / spark.shuffle.compress
            Shuffle过程中是否使用压缩算法对Shuffle数据进行压缩,默认都是True
            前者针对Spill的中间数据,
            后者针对最终的shuffle输出文件,
            Shuffle过程中数据是否应该压缩,取决于CPU/DISK/NETWORK的实际能力和负载,应该综合考虑

*Storage相关配置参数*
        spark.local.dir 
            Spark用于写中间数据,如RDD Cache,Shuffle,Spill等数据的位置
            1.我们可以配置多个路径(用逗号分隔)到多个磁盘上增加整体IO带宽
            2.如果存储设备有快有慢,可以通过在快的设备上配置更多的目录路径来增大它被Spark使用的比例。
            终级方案:像目前HDFS的实现方向一样,让Spark能够感知具体的存储设备类型,针对性的使用。
            1.0后 SPARK_LOCAL_DIRS (Standalone, Mesos) or LOCAL_DIRS (YARN) 覆盖这个配置,最终依赖于 cluster-manager(standalone,yarn,mesos) 的设置
        spark.executor.memory
            默认值为0.6,官方文档建议这个比值不要超过JVM Old Gen区域的比值.
            这个参数最终会被设置到Executor的JVM的heap尺寸上,对应的就是Xmx和Xms的值。
            Executor的内存基本上是Executor内部所有任务共享的,需要了解每个任务的数据规模的大小,从而推算出每个Executor大致需要多少内存
                任务所需内存 = 数据集本身(主要依据) + 算法的临时内存空间 
        spark.storage.memoryFraction
            default 0.6 -> Cache数据的大小,剩下的用来保证任务运行。
        spark.streaming.blockInterval
            Spark Streaming里Stream Receiver生成Block的时间间隔,默认200ms.每隔200ms,就从Buffer中生成一个StreamBlock放进队列.等待进一步被存储到BlockManager中供后续计算过程使用.
        spark.streaming.blockQueueSize

*schedule调度相关*
        spark.cores.max
            决定了在Standalone和Mesos模式下,一个Spark应用程序所能申请的CPU Core的数量.
            Yarn模式不起作用,YARN模式下,资源由Yarn统一调度管理,一个应用启动时所申请的CPU资源的数量由Executor的数量和每个Executor中core数量的参数决定
            Standalone中,基本上是优先从每个Worker中申请所能得到的最大数量的CPU core给每个Executor.
        spark.task.cpus
            分配给每个任务的CPU的数量,默认为1,并不能真的控制每个任务实际运行时所使用的CPU的数量.
        spark.scheduler.mode
            单个Spark应用内部调度的时候使用FIFO模式还是Fair模式.只管理一个Spark应用内部的多个没有依赖关系的Job作业的调度策略.
            在Standalone模式下,取决于每个应用所申请和获得的CPU资源的数量,基本是FIFO。
            在Yarn模式,多个Spark应用间的调度策略由Yarn自己的策略配置文件所决定.
        spark.locality.wait
            spark.locality.wait和
            spark.locality.wait.process,
            spark.locality.wait.node, 
            spark.locality.wait.rack
                这几个参数影响了任务分配时的本地性策略的相关细节。
            数据本地性的场合:
                1.数据的来源是HadoopRDD
                2.RDD的数据来源来自于RDD Cache(即由CacheManager从BlockManager中读取,或者Streaming数据源RDD).
            其它情况下,如果不涉及shuffle操作的RDD,不构成划分Stage和Task的基准(shuffle是stage的分界线),不存在判断Locality本地性的问题.
            而如果是ShuffleRDD,其本地性始终为No Prefer,因此其实也无所谓Locality。
            当Spark应用得到一个计算资源时,如果没有满足最佳本地性需求的任务可以运行,那是
                1.运行一个本地性条件稍差一点的任务呢
                2.还是继续等待下一个或许能够满足最佳本地性的计算资源呢?
            这几个参数一起决定了Spark任务调度在得到分配任务时,选择暂时不分配任务,
            而是等待获得满足进程内部/节点内部/机架内部这样的不同层次的本地性资源的最长等待时间.默认都是3000毫秒.
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值