调一调Hive on Spark参数,毫不夸张的说,使其性能达到最大化!
前言
?
Hive on Spark是指使用Spark替代傳統(tǒng)MapReduce作為Hive的執(zhí)行引擎,在HIVE-7292提出。Hive on Spark的效率比on MR要高不少,但是也需要合理調整參數(shù)才能最大化性能,本文簡單列舉一些調優(yōu)項。為了符合實際情況,Spark也采用on YARN部署方式來說明。
Driver參數(shù)
spark.driver.cores
該參數(shù)表示每個Executor可利用的CPU核心數(shù)。其值不宜設定過大,因為Hive的底層以HDFS存儲,而HDFS有時對高并發(fā)寫入處理不太好,容易造成race condition。根據(jù)我們的實踐,設定在3~6之間比較合理。
假設我們使用的服務器單節(jié)點有32個CPU核心可供使用。考慮到系統(tǒng)基礎服務和HDFS等組件的余量,一般會將YARN NodeManager的yarn.nodemanager.resource.cpu-vcores參數(shù)設為28,也就是YARN能夠利用其中的28核,此時將spark.executor.cores設為4最合適,最多可以正好分配給7個Executor而不造成浪費。又假設yarn.nodemanager.resource.cpu-vcores為26,那么將spark.executor.cores設為5最合適,只會剩余1個核。
由于一個Executor需要一個YARN Container來運行,所以還需保證spark.executor.cores的值不能大于單個Container能申請到的最大核心數(shù),即yarn.scheduler.maximum-allocation-vcores的值。
?
spark.executor.memory/spark.yarn.executor.memoryOverhead
這兩個參數(shù)分別表示每個Executor可利用的堆內內存量和堆外內存量。堆內內存越大,Executor就能緩存更多的數(shù)據(jù),在做諸如map join之類的操作時就會更快,但同時也會使得GC變得更麻煩。Hive官方提供了一個計算Executor總內存量的經驗公式,如下:
yarn.nodemanager.resource.memory-mb * (spark.executor.cores / yarn.nodemanager.resource.cpu-vcores)
其實就是按核心數(shù)的比例分配。在計算出來的總內存量中,80%~85%劃分給堆內內存,剩余的劃分給堆外內存。
?
假設集群中單節(jié)點有128G物理內存,yarn.nodemanager.resource.memory-mb(即單個NodeManager能夠利用的主機內存量)設為120G,那么總內存量就是:120 * 1024 * (4 / 28) ≈ 17554MB。再按8:2比例劃分的話,最終spark.executor.memory設為約13166MB,spark.yarn.executor.memoryOverhead設為約4389MB。
?
與上一節(jié)同理,這兩個內存參數(shù)相加的總量也不能超過單個Container最多能申請到的內存量,即yarn.scheduler.maximum-allocation-mb。
?
spark.executor.instances
該參數(shù)表示執(zhí)行查詢時一共啟動多少個Executor實例,這取決于每個節(jié)點的資源分配情況以及集群的節(jié)點數(shù)。若我們一共有10臺32C/128G的節(jié)點,并按照上述配置(即每個節(jié)點承載7個Executor),那么理論上講我們可以將spark.executor.instances設為70,以使集群資源最大化利用。但是實際上一般都會適當設小一些(推薦是理論值的一半左右),因為Driver也要占用資源,并且一個YARN集群往往還要承載除了Hive on Spark之外的其他業(yè)務。
?
spark.dynamicAllocation.enabled
上面所說的固定分配Executor數(shù)量的方式可能不太靈活,尤其是在Hive集群面向很多用戶提供分析服務的情況下。所以更推薦將spark.dynamicAllocation.enabled參數(shù)設為true,以啟用Executor動態(tài)分配。
?
Driver參數(shù)
spark.driver.cores
該參數(shù)表示每個Driver可利用的CPU核心數(shù)。絕大多數(shù)情況下設為1都夠用。
spark.driver.memory/spark.driver.memoryOverhead
這兩個參數(shù)分別表示每個Driver可利用的堆內內存量和堆外內存量。根據(jù)資源富余程度和作業(yè)的大小,一般是將總量控制在512MB~4GB之間,并且沿用Executor內存的“二八分配方式”。例如,spark.driver.memory可以設為約819MB,spark.driver.memoryOverhead設為約205MB,加起來正好1G。
?
Hive參數(shù)
絕大部分Hive參數(shù)的含義和調優(yōu)方法都與on MR時相同,但仍有兩個需要注意。
?
hive.auto.convert.join.noconditionaltask.size
我們知道,當Hive中做join操作的表有一方是小表時,如果hive.auto.convert.join和hive.auto.convert.join.noconditionaltask開關都為true(默認即如此),就會自動轉換成比較高效的map-side join。而hive.auto.convert.join.noconditionaltask.size這個參數(shù)就是map join轉化的閾值,在Hive on MR下默認為10MB。
?
但是Hive on MR下統(tǒng)計表的大小時,使用的是數(shù)據(jù)在磁盤上存儲的近似大小,而Hive on Spark下則改用在內存中存儲的近似大小。由于HDFS上的數(shù)據(jù)很有可能被壓縮或序列化,使得大小減小,所以由MR遷移到Spark時要適當調高這個參數(shù),以保證map join正常轉換。一般會設為100~200MB左右,如果內存充裕,可以更大點。
?
hive.merge.sparkfiles
小文件是HDFS的天敵,所以Hive原生提供了合并小文件的選項,在on ?MR時是hive.merge.mapredfiles,但是on Spark時會改成hive.merge.sparkfiles,注意要把這個參數(shù)設為true。至于小文件合并的閾值參數(shù),即hive.merge.smallfiles.avgsize與hive.merge.size.per.task都沒有變化。
總結
以上是生活随笔為你收集整理的调一调Hive on Spark参数,毫不夸张的说,使其性能达到最大化!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 从vivo 大规模特征存储实践中学点经验
- 下一篇: 设置网页背景图片不显示