天天看點

基于CDH 6.3.0 搭建 Hive on Spark 及相關配置和調優

 hive預設使用的計算架構是mapreduce,在我們使用hive的時候通過寫sql語句,hive會自動将sql語句轉化成mapreduce作業去執行,但是mapreduce的執行速度遠差于spark。通過搭建一個hive on spark可以修改hive底層的計算引擎,将mapreduce替換成spark,進而大幅度提升計算速度。接下來就如何搭建hive onspark

展開描述。

  注:叢集使用的是cdh6.3.0,使用的spark版本是2.4.0,使用的叢集配置為5個nodemanager節點,每台記憶體62.8g(64g),cpu 32 core。

1.  

配置spark

  給yarn配置設定完資源後,需要配置一些spark的參數,設定spark可使用的資源。包括executor和driver的記憶體,配置設定executor和設定并行度。

1)   配置executor記憶體

  在配置executor的記憶體大小的時候,需要考慮以下因素:

增加executor的記憶體可以優化map join。但是會增加gc的時間。在某些情況下,hdfs用戶端沒有并行處理多個寫請求,在有多個請求競争資源的時候會出現一個executor使用過多的core。盡可能的減少空閑的core的個數,cloudera推薦設定spark.executor.cores為4,5,6,這取決于給yarn配置設定的資源。本叢集有155個core可用,将spark.executor.cores設定為5,這樣155/5餘數為0,設定為6的話會剩餘5個空閑,設定為4的話有3個空閑。這樣配置之後可以同時運作31個executor,每個executor最多可以運作5個任務(每個core一個)。

spark.executor.memory,hive中設定,代表hive 在 spark 上運作時每個 spark 執行程式的 java 堆棧記憶體的最大大小,本叢集設為8g,該值不能太大也不能太小,都會導緻任務直接失敗。executor執行的時候,用的記憶體可能會超過該值設定的大小,是以會為executor額外預留一部分記憶體。spark.yarn.executor.memoryoverhead(hive中設定)代表了這部分記憶體,本叢集設定為2g。

yarn.scheduler.maximum-allocation-mb這個參數表示每個container能夠申請到的最大記憶體,一般是叢集統一配置。spark中的executor程序是跑在container中,是以container的最大記憶體會直接影響到executor的最大可用記憶體。但是當設定一個比較大的記憶體時,日志中會報錯,同時會列印這個參數的值。還有一點是要spark.yarn.executor.memoryoverhead和spark.executor.memory的和不能超過yarn.scheduler.maximum-allocation-mb(yarn參數)設定的值。本叢集scheduler請求最大記憶體配置設定的是60g,即某些情況下允許所有可用記憶體都給某一個executor使用,預留2.8g給系統。

2)   配置driver記憶體

  sparkdriver

端的配置如下:

spark.driver.memory:當hive運作在spark上時,driver端可用的最大java堆記憶體。

spark.yarn.driver.memoryoverhead:每個driver可以額外從yarn請求的堆記憶體大小。這兩個參數和就是yarn為driver端的jvm配置設定的總記憶體。

  spark在driver端的記憶體不會直接影響性能,但是在沒有足夠記憶體的情況下在driver端強制運作spark任務需要調整。本叢集分别設定為3g和1g。

3)   動态配置設定executor(hive中設定)

  設定spark.executor.instances到最大值可以使得spark叢集發揮最大性能。但是這樣有個問題是當叢集有多個使用者運作hive查詢時會有問題,應避免為每個使用者的會話配置設定固定數量的executor,因為executor配置設定後不能回其他使用者的查詢使用,如果有空閑的executor,在生産環境中,計劃配置設定好executor可以更充分的利用spark叢集資源。

spark允許動态的給spark作業配置設定叢集資源,cloudera推薦開啟動态配置設定,本叢集也開啟該設定。

4)   設定并行度

為了更加充分的利用executor,必須同時允許足夠多的并行任務。在大多數情況下,hive會自動決定并行度,但是有時候我們可能會手動的調整并行度。在輸入端,maptask

的個數等于輸入端按照一定格式切分的生成的數目,hiveon spark

的輸入格式是combinehiveinputformat,可以根據需要切分底層輸入格式。調整hive.exec.reducers.bytes.per.reducer控制每個reducer處理多少資料。但是實際情況下,spark相比于mapreduce,對于指定的hive.exec.reducers.bytes.per.reducer不敏感。我們需要足夠的任務讓可用的executor保持工作不空閑,當hive能夠生成足夠多的任務,盡可能的利用空閑的executor。

2.g1 gc

調優

參數配置的位置:spark-defaults.conf,在 spark 配置中檢視如下:

具體屬性名稱為:spark.executor.extrajavaoptions,在“=“後面添加相關屬性,本次調優中加入的參數如下:

spark.executor.extrajavaoptions=-xx:+useg1gc-xx:initiatingheapoccupancypercent=35 -xx:concgcthreads=20 -xx:+printflagsfinal

-xx:+printreferencegc  -verbose:gc

-xx:+printgcdetails -xx:+printgctimestamps -xx:+printadaptivesizepolicy

-xx:+unlockdiagnosticvmoptions -xx:+g1summarizeconcmark -xx:newratio=1

本次針對調優的sql為:

在executor頁面檢視顯示gc占用運作時間超過10%至30%以上,嚴重影響程式運作效率,通過分析sql本身和gc資訊發現,新生代對象很對,占用空間很大:

在新生代空間不足的情況下會放到老年代,容易觸發full gc,是以将newratio參數調至1,有效緩解。也試過将參數調至1以下,但是會導緻程式挂起長時間不執行,原因未知。另外考慮到本例中子查詢資料量很大,在g1調優時适當的增加spark.executor.memory的值。

完整的g1參數和說明如下:

<col>

選項/預設值

說明

-xx:+useg1gc

使用 g1 (garbage first) 垃圾收集器

-xx:maxgcpausemillis=n

設定最大gc停頓時間(gc pause time)名額(target). 這是一個軟性名額(soft goal), jvm 會盡量去達成這個目标.

-xx:initiatingheapoccupancypercent=n

啟動并發gc周期時的堆記憶體占用百分比. g1之類的垃圾收集器用它來觸發并發gc周期,基于整個堆的使用率,而不隻是某一代記憶體的使用比. 值為 0 則表示"一直執行gc循環". 預設值為 45.

-xx:newratio=n

新生代與老生代(new/old generation)的大小比例(ratio). 預設值為 2.

-xx:survivorratio=n

eden/survivor 空間大小的比例(ratio). 預設值為 8.

-xx:maxtenuringthreshold=n

提升年老代的最大臨界值(tenuring threshold). 預設值為 15.

-xx:parallelgcthreads=n

設定垃圾收集器在并行階段使用的線程數,預設值随jvm運作的平台不同而不同.

-xx:concgcthreads=n

并發垃圾收集器使用的線程數量. 預設值随jvm運作的平台不同而不同.

-xx:g1reservepercent=n

設定堆記憶體保留為假天花闆的總量,以降低提升失敗的可能性. 預設值是 10.

-xx:g1heapregionsize=n

使用g1時java堆會被分為大小統一的的區(region)。此參數可以指定每個heap區的大小. 預設值将根據 heap size 算出最優解. 最小值為 1mb

-xx:+printflagsfinal -xx:+printreferencegc  -verbose:gc -xx:+printgcdetails -xx:+printgctimestamps -xx:+printadaptivesizepolicy

這些參數用來在stdout中列印gc相關資訊,用于檢視jvm中垃圾回收情況

3.

遇到的問題

q 1:

基于CDH 6.3.0 搭建 Hive on Spark 及相關配置和調優

a1:

this issue occurs when hive connection is used in threads. when onethread using hive connection is executing a query while another thread is trying

close the same hive connection

q2:

基于CDH 6.3.0 搭建 Hive on Spark 及相關配置和調優

a2:

spark.default.parallelism=1000

spark.storage.memoryfraction=0.5

spark.shuffle.memoryfraction=0.3

q3:

基于CDH 6.3.0 搭建 Hive on Spark 及相關配置和調優

a3:将該值設定大一點

基于CDH 6.3.0 搭建 Hive on Spark 及相關配置和調優

q4:yarn 初始化失敗

基于CDH 6.3.0 搭建 Hive on Spark 及相關配置和調優

a4:

yarn配置中查找yarn.nodemanager.local-dirs,然後删除目錄下面usercache中的所有内容,如:rm -rf /data/yarn/nm/usercache/