1. 程式人生 > >hive 調優手段

hive 調優手段

而在 extract 文件合並 udf log 開啟 過程 階段 普通

調優手段

(1)利用列裁剪

當待查詢的表字段較多時,選取需要使用的字段進行查詢,避免直接select *出大表的所有字段,以免當使用Beeline查詢時控制臺輸出緩沖區被大數據量撐爆。

(2)JOIN避免笛卡爾積

JOIN場景應嚴格避免出現笛卡爾積的情況。參與笛卡爾積JOIN的兩個表,交叉關聯後的數據條數是兩個原表記錄數之積,對於JOIN後還有聚合的場景而言,會導致reduce端處理的數據量暴增,極大地影響運行效率。

    以下左圖為笛卡爾積,右圖為正常Join。

(3)啟動謂詞下推

謂詞下推(Predicate Pushdown)是一個邏輯優化:盡早的對底層數據進行過濾以減少後續需要處理的數據量。通過以下參數啟動謂詞下推。

(
4)開啟Map端聚合功能 在map中會做部分聚集操作,能夠使map傳送給reduce的數據量大大減少,從而在一定程度上減輕group by帶來的數據傾斜。通過以下參數開啟map端聚合功能。 (5)使用Hive合並輸入格式 設置Hive合並輸入格式,使Hive在執行map前進行文件合並,使得本輪map處理數據量均衡。通過以下參數設置Hive合並輸入格式。 (6)合並小文件 啟動較多的map或reduce能夠提高並發度,加快任務運行速度;但同時在HDFS上生成的文件數目也會越來越多,給HDFS的NameNode造成內存上壓力,進而影響HDFS讀寫效率。 對於集群的小文件(主要由Hive啟動的MR生成)過多已造成NameNode壓力時,建議在Hive啟動的MR中啟動小文件合並。 小文件合並能夠使本輪map輸出及整個任務輸出的文件完成合並,保證下輪MapReduce任務map處理數據量均衡。 (
7)解決group by造成的數據傾斜 通過開啟group by傾斜優化開關,解決group by數據傾斜問題。 開啟優化開關後group by會啟動兩個MR。第一個 MR Job 中,Map 的輸出結果集合會隨機分布到 Reduce 中,每個Reduce做部分聚合操作,並輸出結果,這樣處理的結果是相同的Group By Key有可能被分發到不同的Reduce中,從而達到負載均衡的目的;第二個MR Job再根據預處理的數據結果按照Group By Key分布到Reduce中(這個過程可以保證相同的Group By Key被分布到同一個Reduce中),最後完成最終的聚合操作。 (
8)解決Join造成的數據傾斜 兩個表關聯鍵的數據分布傾斜,會形成Skew Join。 解決方案是將這類傾斜的特殊值(記錄數超過hive.skewjoin.key參數值)不落入reduce計算,而是先寫入HDFS,然後再啟動一輪MapJoin專門做這類特殊值的計算,期望能提高計算這部分值的處理速度。設置以下參數。 (9)合理調整map和reduce的內存及虛擬核數 map和reduce的內存及虛擬核數設置,決定了集群資源所能同時啟動的container個數,影響集群並行計算的能力。 對於當前任務是CPU密集型任務(如復雜數學計算)的場景:在map和reduce的虛擬核數默認值基礎上,逐漸增大虛擬核數進行調試(mapreduce.map.cpu.vcores和mapreduce.reduce.cpu.vcores參數控制),但不要超過可分配給container的虛擬核數(yarn.nodemanager.resource.cpu-vcores參數控制)。 對於當前任務是內存密集型任務(如ORC文件讀取/寫入、全局排序)的場景:在map和reduce的內存默認值基礎上,逐漸增大內存值進行調試(mapreduce.map.memory.mb和mapreduce.reduce.memory.mb參數控制),但不要超過當前NodeManager上可運行的所有容器的物理內存總大小(yarn.nodemanager.resource.memory-mb參數控制)。 (10)合理控制map的數量 map的數量會影響MapReduce掃描、過濾數據的效率。 對於掃描、過濾數據的邏輯比較復雜、輸入數據量較大條數較多的場景:根據集群總體資源情況,以及分配給當前租戶的資源情況,在不影響其他業務正常運行的條件下,map數量需要適當增大,增加並行處理的力度。 (11)合理控制reduce的數量 reduce數量會影響MapReduce過濾、聚合、對數據排序的效率。 對於關聯、聚合、排序時reduce端待處理數據量較大的場景:首先根據每個reduce處理的合適數據量控制reduce的個數,如果每個reduce處理數據仍然很慢,再考慮設置參數增大reduce個數。另一方面,控制能啟動的reduce最大個數為分配給當前租戶的資源上限,以免影響其他業務的正常運行。 (12)將重復的子查詢結果保存到中間表 對於指標計算類型的業務場景,多個指標的HQL語句中可能存在相同的子查詢,為避免重復計算浪費計算資源,考慮將重復的子查詢的計算結果保存到中間表,實現計算一次、結果共享的優化目標。 (13)啟用相關性優化器 相關性優化,旨在利用下面兩種查詢的相關性: (a)輸入相關性:在原始operator樹中,同一個輸入表被多個MapReduce任務同時使用的場景; (b)作業流程的相關性:兩個有依賴關系的MapReduce的任務的shuffle方式相同。 通過以下參數啟用相關性優化: 相關參考: https://cwiki.apache.org/confluence/display/Hive/Correlation+Optimizer 14)啟用基於代價的優化 基於代價的優化器,可以基於代價(包括FS讀寫、CPU、IO等)對查詢計劃進行進一步的優化選擇,提升Hive查詢的響應速度。 通過以下參數啟用基於代價的優化: 相關參考: https://cwiki.apache.org/confluence/display/Hive/Cost-based+optimization+in+Hive 15)啟用向量化查詢引擎 傳統方式中,對數據的處理是以行為單位,依次處理的。Hive也采用了這種方案。這種方案帶來的問題是,針對每一行數據,都要進行數據解析,條件判斷,方法調用等操作,從而導致了低效的CPU利用。 向量化特性,通過每次處理1024行數據,列方式處理,從而減少了方法調用,降低了CPU消耗,提高了CPU利用率。結合JDK1.8對SIMD的支持,獲得了極高的性能提升。 通過以下參數啟用向量化查詢引擎: 相關參考: https://cwiki.apache.org/confluence/display/Hive/Vectorized+Query+Execution 16)啟用Join相關優化 (a)使用MapJoin。MapJoin是針對以下場景進行的優化:兩個待連接表中,有一個表非常大,而另一個表非常小,以至於小表可以直接存放到內存中。這樣小表復制多份,在每個map task內存中存在一份(比如存放到hash table中),然後只掃描大表。對於大表中的每一條記錄key/value,在hash table中查找是否有相同的key的記錄,如果有,則連接後輸出即可。 (b)使用SMB Join。 相關參考: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+JoinOptimization 17)使用Multiple Insert特性 以下左圖為普通insert,右圖為Multiple Insert,減少了MR個數,提升了效率。 (18)使用TABLESAMPLE取樣查詢 在Hive中提供了數據取樣(SAMPLING)的功能,用來從Hive表中根據一定的規則進行數據取樣,Hive中的數據取樣支持數據塊取樣和分桶表取樣。 以下左圖為數據塊取樣,右圖為分桶表取樣: (19)啟用Limit優化 啟用limit優化後,使用limit不再是全表查出,而是抽樣查詢。涉及參數如下: (20)利用局部排序 Hive中使用order by完成全局排序,正常情況下,order by所啟動的MR僅有一個reducer,這使得大數據量的表在全局排序時非常低效和耗時。 當全局排序為非必須的場景時,可以使用sort by在每個reducer範圍進行內部排序。同時可以使用distribute by控制每行記錄分配到哪個reducer。 (21)慎用低性能的UDF和SerDe 慎用低性能的UDF和SerDe,主要指謹慎使用正則表達式類型的UDF和SerDe。如:regexp、regexp_extract、regexp_replace、rlike、RegexSerDe。 當待處理表的條數很多時,如上億條,采用諸如([^ ]*)([^ ]*)([^]*)(.?)(\".*?\")(-|[0-9]*)(-|[0-9]*)(\".*?\")(\".*?\")這種復雜類型的正則表達式組成過濾條件去匹配記錄,會嚴重地影響map階段的過濾速度。 建議在充分理解業務需求後,自行編寫更高效準確的UDF實現相應的功能。 (22)優化count(distinct) 優化方式如下,左圖為原始HQL,右圖為優化後HQL。 (23)改用MR實現 在某些場景下,直接編寫MR比使用HQL更加高效。

hive 調優手段