Spark2内存调优总结 - 内存划分 与 内存计算 与 调参方式
使用的Spark2以上版本所以只考慮UnifiedMemoryManager動態(tài)內(nèi)存管理,如圖:
1. 內(nèi)存劃分 與 內(nèi)存計(jì)算 與 調(diào)參方式
1.1 三部分:Spark內(nèi)存、用戶內(nèi)存、預(yù)留內(nèi)存
假設(shè):我們在submit提交參數(shù)設(shè)置 executor.memeory = 10G + 300M (方便計(jì)算),我們叫他為系統(tǒng)內(nèi)存
那么:
Spark內(nèi)存 = (系統(tǒng)內(nèi)存 - 預(yù)留內(nèi)存) fraction = (10G + 300M - 300M) * 0.75 = 7.5G*
用戶內(nèi)存 = (系統(tǒng)內(nèi)存 - 預(yù)留內(nèi)存) (1 - fraction) = 10 G * (1 - 0.75) = 2.5G*
1.2 Spark內(nèi)存又分為兩部分:存儲內(nèi)存、執(zhí)行內(nèi)存
假設(shè):1.1的計(jì)算成立
那么:
存儲內(nèi)存 = Spark內(nèi)存*storageFraction = 7.5G * 0.5 = 3.75G
執(zhí)行內(nèi)存 = Spark內(nèi)存*storageFraction = 7.5G * (1 - 0.5) = 3.75G
2. 內(nèi)存參數(shù)調(diào)優(yōu)
可以看出來實(shí)際設(shè)置了10G,而執(zhí)行內(nèi)存卻只有了3.5G,所以需要根據(jù)業(yè)務(wù)來進(jìn)行參數(shù)調(diào)整。
2.1 調(diào)大spark.memory.storageFraction=0.6
如果程序中有需要使用內(nèi)存Cache的而不需要太多計(jì)算shuffer之類的那么可以增加存儲內(nèi)存,調(diào)大spark.memory.storageFraction參數(shù)
2.2 調(diào)小spark.memory.storageFraction=0.3
3. 再說一點(diǎn):JVM參數(shù)調(diào)整
說一個(gè)案例:
假設(shè):
1.Spark讀取的是HDFS上的文件,HDFS上默認(rèn)的Block塊大小為128M
每個(gè)executor有8個(gè)core,executor-cores來設(shè)置
估算Eden = 700M* 3 * 8 大約 16G
-Xmn = 4/3 * 16G 大約 21.5GB,才能保證程序可以正常執(zhí)行,要不然很容易出現(xiàn)OOM,當(dāng)前還可以設(shè)置堆外內(nèi)存來緩解壓力--conf spark.memory.offHeap.size=5g
3.1 -Xmn
-Xmn這里需要多說一下,經(jīng)過線上執(zhí)行情況分析,一開始使用的-Xmn=18G,Spark程序執(zhí)行時(shí)間2.2小時(shí),并伴有幾十次Full GC;去掉-Xmn后,Spark程序執(zhí)行時(shí)間58分鐘,0次Full GC。第二次測試時(shí)我將每個(gè)executor_core設(shè)置為了5,第一次為8,并沒有控制變量,因?yàn)槟康厥莾?yōu)化不是測試。
4.對象的使用
為了減少有些數(shù)據(jù)結(jié)構(gòu)與對象的元數(shù)據(jù)占用大量空間,盡量使用:
字符串代替對象,基本數(shù)據(jù)類型(int long)代替字符串,數(shù)組代替ArrayList等
String內(nèi)部是一個(gè)char數(shù)據(jù),char采用UTF-16編碼,每個(gè)字符兩字節(jié),可以設(shè)置JVM參數(shù) -XX:+UseCompressedStrings采用8位來編碼每一個(gè)ASCII字符來壓縮字符。
下面是我的參數(shù),需要根據(jù)自己的程序去修改一些參數(shù)值:
# submit參數(shù) spark-submit --master spark://192.168.11.167:7077 \ --class $main --deploy-mode client --driver-memory 25g \ --executor-memory 45g \ --executor-cores 8 \ --total-executor-cores 320 \ --conf spark.memory.fraction=0.8 \ --conf spark.memory.storageFraction=0.3 \ --conf spark.memory.offHeap.enabled=true \ --conf spark.memory.offHeap.size=5g \ --conf spark.executor.memoryOverhead=5G \ --conf spark.speculation=true \ --conf spark.network.timeout=3000 \ --conf spark.executor.extraJavaOptions="-XX:+UseG1GC -XX:-TieredCompilation -XX:G1HeapRegionSize=16m -XX:InitiatingHeapOccupancyPercent=55 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:-UseCompressedClassPointers -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m -XX:ReservedCodeCacheSize=512m -XX:+UseCodeCacheFlushing -XX:ParallelGCThreads=20 -XX:ConcGCThreads=20 -Xms20g -XX:+PrintGCDetails -XX:+PrintGCTimeStamps" \ --conf spark.driver.extraJavaOptions="-XX:+UseG1GC" \ --jars $jars xxxx.jar $date1 $max $date2 >> log/$log_file#代碼內(nèi)參數(shù) conf.set("spark.driver.maxResultSize", "8g"); conf.set("spark.serialize", "org.apache.spark.serializer.KryoSerializer"); conf.registerKryoClasses(new Class[]{ImmutableBytesWritable.class, HyperLogLog.class, HashSet.class, RegisterSet.class, IllegalArgumentException.class, FileCommitProtocol.TaskCommitMessage.class}); //conf.set("spark.kryo.registrationRequired","true"); #開啟的話類沒加到上面會報(bào)錯(cuò) conf.set("spark.kryoserializer.buffer.mb", "10"); conf.set("spark.shuffle.file.buffer", "128"); conf.set("spark.reducer.maxSizeInFlight", "144"); conf.set("spark.shuffle.io.maxRetries", "50"); conf.set("spark.shuffle.io.retryWait", "5s");總結(jié)
以上是生活随笔為你收集整理的Spark2内存调优总结 - 内存划分 与 内存计算 与 调参方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小米POCO F4宣布:骁龙870直屏旗
- 下一篇: 投资100万,每天收益1000元,算不算