沙龙晃荡 | 去哪儿、陌陌、ThoughtWorks在主动化运维中的实践!10.28不见不散!
在这份100行的代率攀里,一共有 3 次 shuffle 操作,义务被 spark driver 切分成了 4 个 stage 串行履行,代码地位如下:
0、背景
日前接到反馈,集群部分 spark 义务履行很慢,且经常掉足,参数改来改去怎么都无法优化其机能和解决频繁随机报错的问题。
看了下义务的汗青运行情况,平均时光 3h 阁下,并且极其不稳定,有时还会报错:

义务的运行时光跟什么竽暌剐关?
(1)数据源大年夜小差别
在有限的计算下,job的运行时长和数据量大年夜小正相干,在本例中,数据量大年夜小根本稳定,可以清除是日记量级波动导致的问题:
(2)代码本身逻辑缺点

咱们须要做的就是大年夜算法和营业角度尽可能削减 shuffle 和 stage,晋升并行枷⒚机能,这块是个大年夜的话题,本次不展开胪陈。
(3)参数设置不合理
这块技能相对通用,咱们来看看之前的核心参数设置:
- num-executors=10 || 20 ,executor-cores=1 || 2, executor-memory= 10 || 20,driver-memory=20,spark.default.parallelism=64
比如代率攀里反复创建、初始化变量、情况、RDD资本等,随便持久化数据等,大年夜量应用 shuffle 算子等,比如reduceByKey、join等算子。
- memory=1T,cores=400
参数怎么设置在这里就有些技能了,起首得明白 spark 资本的分派和应用道理:
在默认的非动态资本分派场景下, spark 是预申请资本,义务还没起跑就独有资本,一向到全部 job 所有 task 停止,比如你跳板机起了一个 spark-shell 一向没退出,也没履行义务,那也会一向占领所有申请的资本。(如不雅设置了 num-executors,动态资本分派会掉效)
留意膳绫擎这句话,spark 的资本应用分派方法和 mapreduce/hive 是有很大年夜差其余,如不雅不睬解这个问题就会在参数设置上激发其它问题。
比如 executor-cores 设若干合适?少了义务并行度不可,多了会把全部队列资本独有耗光,其他同窗的义务都无法履行,比瘸琅绫擎那个义务,在 num-executors=20 executor-cores=1 executor-memory= 10 的情况下,会独有20个cores,200G内存,一向持续3个小时。
那针对本case中的义务,结合咱们现有的资本,若何设置这 5 个核心参数呢?
- 1) executor_cores*num_executors 不宜太小或太大年夜!一般不跨越总队列 cores 的 25%,比如队列总 cores 400,最大年夜不要跨越100,最小不建议低于 40,除非日记量很小。
- 2) executor_cores 不宜为1!不然 work 过程中线程数过少,一般 2~4 为宜。
- 3) executor_memory 一般 6~10g 为宜,最大年夜不跨越 20G,不然会导致 GC 价值过高,或资本浪费严重。
- 4) spark_parallelism 一般为 executor_cores*num_executors 的 1~4 倍,体系默认值 64,不设置的话会导致 task 很多的时刻被分批串行履行,或大年夜量 cores 余暇,资本浪费严重。
- 5) driver-memory 早前有同窗设置 20G,其实 driver 不做任何计算和存储,只是下发义务与yarn资本治理器和task交互,除非你是 spark-shell,不然一般 1-2g 就够了。
Spark Memory Manager:
- 6)spark.shuffle.memoryFraction(默认 0.2) ,也叫 ExecutionMemory。这片内存区域是为懂得决 shuffles,joins, sorts and aggregations 过程中为了避免频繁IO须要的buffer。如不雅你的法度榜样有大年夜量这类操作可以恰当调高。
- 7)spark.storage.memoryFraction(默认0.6),也叫 StorageMemory。这片内存区域是为懂得决 block cache(就是你显示调用dd.cache, rdd.persist等办法), 还有就是broadcasts,以及task results的存储。可以经由过程参数,如不雅你大年夜量调用了持久化操作或广播变量,那可以恰当调高它。
- 8)OtherMemory,给体系预留的,因为法度榜样本身运行也是须要内存的, (默认为0.2)。Other memory在1.6也做了调剂,包管至少有300m可用。你也可以手动设置 spark.testing.reservedMemory . 然后把实际可用内存减去这个reservedMemory获得 usableMemory。 ExecutionMemory 和 StorageMemory 会共享usableMemory * 0.75的内存。0.75可以经由过程 新参数 spark.memory.fraction 设置。今朝spark.memory.storageFraction 默认值是0.5,所以ExecutionMemory,StorageMemory默认情况是均分膳绫擎提到的可用内存的。
假设咱们的 spark 队列资本情况如下:
例如,如不雅须要加载大年夜的字典文件,可以增大年夜executor中 StorageMemory 的大年夜小,如许就可以避免全局字典换入换出,削减GC,在这种情况下,我们相当于用内存资本来换取了履行效力。
(5)其它优化角度
效不雅如下:
推荐阅读
沙龙晃荡 | 去哪儿、陌陌、ThoughtWorks在主动化运维中的实践!10.28不见不散! 文┞仿的大年夜致构造:第一部分,分布式体系的根本概念;第二、三部分分别具体阐述数据存储和数据计算体系;>>>详细阅读
本文标题:手把手教你Spark性能调优
地址:http://www.17bianji.com/lsqh/38089.html
1/2 1

网友点评
精彩导读
科技快报
品牌展示