前言
node
Hive on Spark是指使用Spark替代傳統MapReduce做爲Hive的執行引擎,在HIVE-7292提出。Hive on Spark的效率比on MR要高很多,可是也須要合理調整參數才能最大化性能,本文簡單列舉一些調優項。爲了符合實際狀況,Spark也採用on YARN部署方式來講明。緩存
Driver參數
服務器
spark.driver.cores
該參數表示每一個Executor可利用的CPU核心數。其值不宜設定過大,由於Hive的底層以HDFS存儲,而HDFS有時對高併發寫入處理不太好,容易形成race condition。根據咱們的實踐,設定在3~6之間比較合理。併發
假設咱們使用的服務器單節點有32個CPU核心可供使用。考慮到系統基礎服務和HDFS等組件的餘量,通常會將YARN NodeManager的yarn.nodemanager.resource.cpu-vcores
參數設爲28,也就是YARN可以利用其中的28核,此時將spark.executor.cores
設爲4最合適,最多能夠正好分配給7個Executor而不形成浪費。又假設yarn.nodemanager.resource.cpu-vcores
爲26,那麼將spark.executor.cores
設爲5最合適,只會剩餘1個核。ide
因爲一個Executor須要一個YARN Container來運行,因此還需保證spark.executor.cores
的值不能大於單個Container能申請到的最大核心數,即yarn.scheduler.maximum-allocation-vcores
的值。高併發
spark.executor.memory/spark.yarn.executor.memoryOverhead
這兩個參數分別表示每一個Executor可利用的堆內內存量和堆外內存量。堆內內存越大,Executor就能緩存更多的數據,在作諸如map join之類的操做時就會更快,但同時也會使得GC變得更麻煩。Hive官方提供了一個計算Executor總內存量的經驗公式,以下:性能
yarn.nodemanager.resource.memory-mb * (spark.executor.cores / yarn.nodemanager.resource.cpu-vcores)
spa
其實就是按核心數的比例分配。在計算出來的總內存量中,80%~85%劃分給堆內內存,剩餘的劃分給堆外內存。code
假設集羣中單節點有128G物理內存,yarn.nodemanager.resource.memory-mb
(即單個NodeManager可以利用的主機內存量)設爲120G,那麼總內存量就是:120 * 1024 * (4 / 28) ≈ 17554MB。再按8:2比例劃分的話,最終spark.executor.memory
設爲約13166MB,spark.yarn.executor.memoryOverhead
設爲約4389MB。內存
與上一節同理,這兩個內存參數相加的總量也不能超過單個Container最多能申請到的內存量,即yarn.scheduler.maximum-allocation-mb
。
spark.executor.instances
該參數表示執行查詢時一共啓動多少個Executor實例,這取決於每一個節點的資源分配狀況以及集羣的節點數。若咱們一共有10臺32C/128G的節點,並按照上述配置(即每一個節點承載7個Executor),那麼理論上講咱們能夠將spark.executor.instances
設爲70,以使集羣資源最大化利用。可是實際上通常都會適當設小一些(推薦是理論值的一半左右),由於Driver也要佔用資源,而且一個YARN集羣每每還要承載除了Hive on Spark以外的其餘業務。
spark.dynamicAllocation.enabled
上面所說的固定分配Executor數量的方式可能不太靈活,尤爲是在Hive集羣面向不少用戶提供分析服務的狀況下。因此更推薦將spark.dynamicAllocation.enabled
參數設爲true,以啓用Executor動態分配。
Driver參數
spark.driver.cores
該參數表示每一個Driver可利用的CPU核心數。絕大多數狀況下設爲1都夠用。
spark.driver.memory/spark.driver.memoryOverhead
這兩個參數分別表示每一個Driver可利用的堆內內存量和堆外內存量。根據資源富餘程度和做業的大小,通常是將總量控制在512MB~4GB之間,而且沿用Executor內存的「二八分配方式」。例如,spark.driver.memory
能夠設爲約819MB,spark.driver.memoryOverhead
設爲約205MB,加起來正好1G。
Hive參數
絕大部分Hive參數的含義和調優方法都與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
這個參數就是map join轉化的閾值,在Hive on MR下默認爲10MB。
可是Hive on MR下統計表的大小時,使用的是數據在磁盤上存儲的近似大小,而Hive on Spark下則改用在內存中存儲的近似大小。因爲HDFS上的數據頗有可能被壓縮或序列化,使得大小減少,因此由MR遷移到Spark時要適當調高這個參數,以保證map join正常轉換。通常會設爲100~200MB左右,若是內存充裕,能夠更大點。
hive.merge.sparkfiles
小文件是HDFS的天敵,因此Hive原生提供了合併小文件的選項,在on MR時是hive.merge.mapredfiles
,可是on Spark時會改爲hive.merge.sparkfiles
,注意要把這個參數設爲true。至於小文件合併的閾值參數,即hive.merge.smallfiles.avgsize
與hive.merge.size.per.task
都沒有變化。