一也物、基礎配置
我們公司yarn node節(jié)點的可用資源配置為:單臺node節(jié)點可用資源數(shù):核數(shù)33cores搁吓、內存110G。Hive on Spark任務的基礎配置澈蟆,主要配置對象包括:Executor和Driver內存趟径,Executor配額瘪吏,任務并行度。
1蜗巧、Executor內存和核數(shù)
配置參數(shù)為spark.executor.memory和spark.executor.cores掌眠。如果要最大化使用core,建議將core設置為4幕屹、5蓝丙、6,且滿足core的個數(shù)盡量可以整除yarn資源核數(shù)望拖。yarn資源可用33核渺尘,建議spark.executor.cores設置為4,最多剩下一個core说敏,如果設置為5沧烈,6都會有3個core剩余。 spark.executor.cores=4像云,由于總共有33個核,那么最大可以申請的executor數(shù)是8蚂夕⊙肝埽總內存處以8,也即是 110/8婿牍,可以得到每個executor約13.75GB內存侈贷。
建議 spark.executor.memoryOverhead(spark的executor堆外內存)站總內存的 15%-20%询微。 那么最終 spark.executor.memoryOverhead=2.75 G 和spark.executor.memory=11 G
注意:默認情況下 spark.executor.memoryOverhead = max(executorMemory * 0.10, 384M)撞叽,正常情況下不需要手動設置spark堆外內存,如果spark任務出現(xiàn)如下報錯麦撵,可以手動提高堆外內存大小上遥。
注意:默認情況下 spark.executor.memoryOverhead = max(executorMemory * 0.10, 384M)搏屑,正常情況下不需要手動設置spark堆外內存,如果spark任務出現(xiàn)如下報錯粉楚,可以手動提高堆外內存大小辣恋。
Container killed by YARN for exceeding memory limits. 16.9 GB of 16 GB physical memory used. Consider boosting spark.yarn.executor.memoryOverhead.
2亮垫、Driver內存
對于drvier的內存配置,主要有兩個參數(shù):
- spark.driver.memoryOverhead 每個driver能從yarn申請的堆外內存的大小伟骨。
- spark.driver.memory 當運行hive on spark的時候饮潦,每個spark driver能申請的最大jvm 堆內存。該參數(shù)結合 spark.driver.memoryOverhead共同決定著driver的內存大小携狭。
Driver的內存通常來說不設置继蜡,或者設置1G左右應該就夠了。需要注意的是逛腿,如果需要使用collect算子將RDD的數(shù)據(jù)全部拉取到Driver端進行處理稀并,那么必須確保Driver的內存足夠大,否則會出現(xiàn)OOM內存溢出的問題鳄逾。
3稻轨、Executor個數(shù)
配置參數(shù)為spark.executor.instances。該參數(shù)用于設置Spark作業(yè)總共要用多少個Executor進程來執(zhí)行雕凹。
executor的數(shù)目是由每個節(jié)點運行的executor數(shù)目和集群的節(jié)點數(shù)共同決定殴俱。我們離線集群27個節(jié)點,那么離線spark任務使用的最大executor數(shù)就是 216(27*8). 最大數(shù)目可能比這個小點枚抵,因為driver也會消耗核數(shù)和內存线欲。
該參數(shù)可以結合spark.executor.cores設置,默認單個spark任務最大不超過60cores汽摹,spark.executor.cores設置為4李丰,則spark.executor.instances不超過15。
4逼泣、并行度
設置spark任務的并行度參數(shù)為spark.default.parallelism趴泌。spark任務每個stage的task個數(shù)=max(spark.default.parallelism, HDFS的block數(shù)量)。如果不設置該參數(shù)拉庶,Spark自己根據(jù)底層HDFS的block數(shù)量來設置task的數(shù)量嗜憔,默認是一個HDFS block對應一個task。spark默認spark.default.parallelism配置較少氏仗,如果task個數(shù)比較少的話吉捶,前面spark資源配置沒有意義。官網(wǎng)建議:該參數(shù)設置為 num-executors * executor-cores的2~3倍較為合適皆尔。
5呐舔、參數(shù)配置
SET hive.execution.engine=spark;
-- 修改spark on yarn的資源隊列
SET spark.yarn.queue=root.dw_offline_day;
-- 設置Driver內存
SET spark.driver.memory=1G;
-- 設置Executor核數(shù)
SET spark.executor.cores=4;
-- 設置Executor內存
SET spark.executor.memory=11G;
-- 設置Executor個數(shù)
SET spark.executor.instances=10;
-- 設置spark任務并行度
SET spark.default.parallelism=120;
二、動態(tài)資源分配
當一個運行時間比較長的spark任務慷蠕,如果分配給他多個Executor珊拼,可是卻沒有task分配給它,而此時有其他的yarn任務資源緊張流炕,這就造成了很大的資源浪費和資源不合理的調度杆麸。動態(tài)資源調度就是為了解決這種場景搁进,根據(jù)當前應用任務的負載情況,實時的增減Executor個數(shù)昔头,從而實現(xiàn)動態(tài)分配資源饼问,使整個Spark系統(tǒng)更加健康。
1揭斧、資源分配策略
開啟spark動態(tài)資源分配后莱革,application會在task因沒有足夠資源被掛起的時候去動態(tài)申請資源。當任務掛起或等待spark.dynamicAllocation.schedulerBacklogTimeout(默認1s)的時間后讹开,會開始動態(tài)資源分配盅视;之后每隔spark.dynamicAllocation.sustainedSchedulerBacklogTimeout(默認1s)時間申請一次,直到申請到足夠的資源旦万。每次申請的資源量是指數(shù)增長的闹击,即1,2,4,8等。
2成艘、資源回收策略
當application的executor空閑時間超過spark.dynamicAllocation.executorIdleTimeout(默認60s)后赏半,就會被回收。
3淆两、參數(shù)配置
SET hive.execution.engine=spark;
-- 修改spark on yarn的資源隊列
SET spark.yarn.queue=root.dw_offline_day;
-- 設置Driver內存
SET spark.driver.memory=1G;
-- 設置Executor核數(shù)
SET spark.executor.cores=4;
-- 設置Executor內存
SET spark.executor.memory=8G;
-- 開啟動態(tài)資源分配
SET spark.dynamicAllocation.enabled=true;
-- 每個Application最小分配的executor數(shù)
SET spark.dynamicAllocation.minExecutors=1;
-- 如果所有的executor都移除了断箫,重新請求時啟動的初始executor數(shù)
SET spark.dynamicAllocation.initialExecutors=1;
-- 每個Application最大并發(fā)分配的executor數(shù)
SET spark.dynamicAllocation.maxExecutors=15;
-- 有新任務處于等待狀態(tài),并且等待時間超過該時間段秋冰,會依次啟動executor, 每次啟動1,2,4,8...個executor
SET spark.dynamicAllocation.schedulerBacklogTimeout=1s;
-- 動態(tài)啟動executor的間隔
SET spark.dynamicAllocation.sustainedSchedulerBacklogTimeout=5s;
三仲义、小文件合并
1、參數(shù)配置
SET hive.merge.mapfiles=true;
SET hive.merge.mapredfiles=false;
SET hive.merge.sparkfiles=true;
-- 當輸出文件的平均大小小于該值時剑勾,啟動單獨的任務進行文件merge
SET hive.merge.smallfiles.avgsize=16000000;
-- 合并文件的大邪D臁(默認256M)
SET hive.merge.size.per.task=256000000;
四、動態(tài)分區(qū)使用
使用場景:同一個SQL語句需要同時更新多個分區(qū)虽另,類似于如下SQL語句:
INSERT OVERWRITE TABLE table_name PARTITION (dt)
SELECT id, name, dt
FROM ...
1盯另、參數(shù)說明
(1)hive.exec.dynamic.partition
- 默認值:false
- 說明:是否啟動動態(tài)分區(qū)
(2)hive.exec.dynamic.partition.mode
- 默認值:strict
- 說明:打開動態(tài)分區(qū)后,動態(tài)分區(qū)的模式洲赵,有strict和nonstrict兩種模式,strict要求至少包含一個靜態(tài)分區(qū)列商蕴,nonstrict則無此要求叠萍。
(3)hive.exec.max.dynamic.partitions
- 默認值:100000
- 說明:允許的最大的動態(tài)分區(qū)的個數(shù)⌒魃蹋可以手動增加分區(qū)苛谷。
(4)hive.exec.max.dynamic.partitions.pernode
- 默認值:100
- 說明:在每個執(zhí)行任務的節(jié)點上,最大可以創(chuàng)建多少個動態(tài)分區(qū)格郁。
(5)hive.exec.default.partition.name
- 默認值: HIVE_DEFAULT_PARTITION
- 說明:在hive里面表可以創(chuàng)建成分區(qū)表腹殿,但是當分區(qū)字段的值是’’ 或者 null時独悴,hive會自動將分區(qū)命名為默認分區(qū)名稱。默認情況下锣尉,默認分區(qū)的名稱為HIVE_DEFAULT_PARTITION刻炒,默認分區(qū)名稱是可配置的。
2自沧、參數(shù)配置
SET hive.exec.dynamic.partition=TRUE;
SET hive.exec.dynamic.partition.mode=nonstrict;
SET hive.exec.max.dynamic.partitions=100000;
SET hive.exec.max.dynamic.partitions.pernode=100000;
四坟奥、Hive參數(shù)配置
1、參數(shù)配置
-- 如果一個簡單查詢只包括一個group by和order by拇厢,此處可以設置為1或2爱谁。適用于模型層維度表處理
SET hive.optimize.reducededuplication.min.reducer=4;
-- 如果數(shù)據(jù)已經(jīng)根據(jù)相同的key做好聚合,那么去除掉多余的map/reduce作業(yè)
SET hive.optimize.reducededuplication=true;
-- Map Join優(yōu)化, 不太大的表直接通過map過程做join
SET hive.auto.convert.join=true;
SET hive.auto.convert.join.noconditionaltask=true;
-- Map Join任務HashMap中key對應value數(shù)量
SET hive.smbjoin.cache.rows=10000;
-- 可以被轉化為HashMap放入內存的表的大小(官方推薦853M)
SET hive.auto.convert.join.noconditionaltask.size=200M;
-- 如果數(shù)據(jù)按照join的key分桶孝偎,hive將簡單優(yōu)化inner join(官方推薦關閉)
SET hive.optimize.bucketmapjoin= false;
SET hive.optimize.bucketmapjoin.sortedmerge=false;
-- 所有map任務可以用作Hashtable的內存百分比, 如果OOM, 調小這個參數(shù)(官方默認0.5)
SET hive.map.aggr.hash.percentmemory=0.5;
-- map端聚合(跟group by有關), 如果開啟, Hive將會在map端做第一級的聚合, 會用更多的內存访敌,開啟這個參數(shù) sum(1)會有類型轉換問題
SET hive.map.aggr=false;
-- 將只有SELECT, FILTER, LIMIT轉化為FETCH, 減少等待時間
SET hive.fetch.task.conversion=more;
SET hive.fetch.task.conversion.threshold=1073741824;
-- 新創(chuàng)建的表/分區(qū)是否自動計算統(tǒng)計數(shù)據(jù)
SET hive.stats.autogather=true;
SET hive.compute.query.using.stats=true;
SET hive.stats.fetch.column.stats=true;
SET hive.stats.fetch.partition.stats=true;
-- 在order by limit查詢中分配給存儲Top K的內存為10%
SET hive.limit.pushdown.memory.usage=0.1;
-- 是否開啟自動使用索引
SET hive.optimize.index.filter=true;