Hive面試題整理(一) ---阿善有用


Hive面試題整理(一)

1、Hive表關聯查詢,如何解決數據傾斜的問題?(☆☆☆☆☆)

  1)傾斜原因:map輸出數據按key Hash的分配到reduce中,由於key分布不均勻、業務數據本身的特、建表時考慮不周、等原因造成的reduce 上的數據量差異過大。
  (1)key分布不均勻;
  (2)業務數據本身的特性;
  (3)建表時考慮不周;
  (4)某些SQL語句本身就有數據傾斜;
  如何避免:對於key為空產生的數據傾斜,可以對其賦予一個隨機值。
  2)解決方案
  (1)參數調節:
    hive.map.aggr = true
    hive.groupby.skewindata=true
  有數據傾斜的時候進行負載均衡,當選項設定位true,生成的查詢計划會有兩個MR Job。第一個MR Job中,Map的輸出結果集合會隨機分布到Reduce中,每個Reduce做部分聚合操作,並輸出結果,這樣處理的結果是相同的Group By Key有可能被分發到不同的Reduce中,從而達到負載均衡的目的;第二個MR Job再根據預處理的數據結果按照Group By Key 分布到 Reduce 中(這個過程可以保證相同的 Group By Key 被分布到同一個Reduce中),最后完成最終的聚合操作。
  (2)SQL 語句調節:
  ① 選用join key分布最均勻的表作為驅動表。做好列裁剪和filter操作,以達到兩表做join 的時候,數據量相對變小的效果。
  ② 大小表Join:
    使用map join讓小的維度表(1000 條以下的記錄條數)先進內存。在map端完成reduce。
  ③ 大表Join大表:
    把空值的key變成一個字符串加上隨機數,把傾斜的數據分到不同的reduce上,由於null 值關聯不上,處理后並不影響最終結果。
  ④ count distinct大量相同特殊值:
    count distinct 時,將值為空的情況單獨處理,如果是計算count distinct,可以不用處理,直接過濾,在最后結果中加1。如果還有其他計算,需要進行group by,可以先將值為空的記錄單獨處理,再和其他計算結果進行union。

2、Hive的HSQL轉換為MapReduce的過程?(☆☆☆☆☆)

HiveSQL ->AST(抽象語法樹) -> QB(查詢塊) ->OperatorTree(操作樹)->優化后的操作樹->mapreduce任務樹->優化后的mapreduce任務樹

 

 

  過程描述如下:
    SQL Parser:Antlr定義SQL的語法規則,完成SQL詞法,語法解析,將SQL轉化為抽象語法樹AST Tree
    Semantic Analyzer:遍歷AST Tree,抽象出查詢的基本組成單元QueryBlock
    Logical plan:遍歷QueryBlock,翻譯為執行操作樹OperatorTree;
    Logical plan optimizer: 邏輯層優化器進行OperatorTree變換合並不必要的ReduceSinkOperator,減少shuffle數據量;
    Physical plan:遍歷OperatorTree,翻譯為MapReduce任務;
    Logical plan optimizer:物理層優化器進行MapReduce任務的變換,生成最終的執行計划。

3、Hive底層與數據庫交互原理?(☆☆☆☆☆)

  由於Hive的元數據可能要面臨不斷地更新、修改和讀取操作,所以它顯然不適合使用Hadoop文件系統進行存儲。目前Hive將元數據存儲在RDBMS中,比如存儲在MySQL、Derby中。元數據信息包括存在的表、表的列、權限和更多的其他信息。

 

4、Hive的兩張表關聯,使用MapReduce怎么實現?(☆☆☆☆☆)

  如果其中有一張表為小表,直接使用map端join的方式(map端加載小表)進行聚合。
  如果兩張都是大表,那么采用聯合key聯合key的第一個組成部分是join on中的公共字段第二部分是一個flag0代表表A,1代表表B由此讓Reduce區分客戶信息和訂單信息;在Mapper中同時處理兩張表的信息,將join on公共字段相同的數據划分到同一個分區中,進而傳遞到一個Reduce中,然后在Reduce中實現聚合。

5、請談一下Hive的特點,Hive和RDBMS有什么異同?

  hive是基於Hadoop的一個數據倉庫工具,可以將結構化的數據文件映射為一張數據庫表,並提供完整的sql查詢功能,可以將sql語句轉換為MapReduce任務進行運行。其優點是學習成本低,可以通過類SQL語句快速實現簡單的MapReduce統計,不必開發專門的MapReduce應用,十分適合數據倉庫的統計分析,但是Hive不支持實時查詢。
  Hive與關系型數據庫的區別:

 

6、請說明hive中 Sort By,Order By,Cluster By,Distrbute By各代表什么意思?

  order by:會對輸入做全局排序,因此只有一個reducer(多個reducer無法保證全局有序)。只有一個reducer,會導致當輸入規模較大時,需要較長的計算時間。
  sort by:不是全局排序,其在數據進入reducer前完成排序。
  distribute by:按照指定的字段對數據進行划分輸出到不同的reduce中。
cluster by:除了具有 distribute by 的功能外還兼具 sort by 的功能。

7、寫出hive中split、coalesce及collect_list函數的用法(可舉例)?

  split將字符串轉化為數組,即:split(‘a,b,c,d’ , ‘,’) ==> [“a”,“b”,“c”,“d”]。
  coalesce(T v1, T v2, …) 返回參數中的第一個非空值;如果所有值都為 NULL,那么返回NULL
  collect_list列出該字段所有的值,不去重 => select collect_list(id) from table。

8、Hive有哪些方式保存元數據,各有哪些特點?

  Hive支持三種不同的元存儲服務器,分別為:內嵌式元存儲服務器、本地元存儲服務器、遠程元存儲服務器,每種存儲方式使用不同的配置參數。
  內嵌式元存儲主要用於單元測試,在該模式下每次只有一個進程可以連接到元存儲,Derby是內嵌式元存儲的默認數據庫。
  在本地模式下,每個Hive客戶端都會打開到數據存儲的連接並在該連接上請求SQL查詢。
  在遠程模式下,所有的Hive客戶端都將打開一個到元數據服務器的連接,該服務器依次查詢元數據,元數據服務器和客戶端之間使用Thrift協議通信。 


11、所有的Hive任務都會有MapReduce的執行嗎?

  不是,從Hive0.10.0版本開始,對於簡單的不需要聚合的類似SELECT from

LIMIT n語句,不需要起MapReduce job,直接通過Fetch task獲取數據。

 

 

12、Hive的函數:UDF、UDAF、UDTF的區別?

  UDF:單行進入,單行輸出
  UDAF:多行進入,單行輸出
  UDTF:單行輸入,多行輸出

13、說說對Hive桶表的理解?

  桶表是對數據進行哈希取值,然后放到不同文件中存儲。
數據加載到桶表時,會對字段取hash值然后與桶的數量取模。把數據放到對應的文件中。物理上,每個桶就是表(或分區)目錄里的一個文件,一個作業產生的桶(輸出文件)和reduce任務個數相同
  桶表專門用於抽樣查詢,是很專業性的,不是日常用來存儲數據的表,需要抽樣查詢時,才創建和使用桶表。

Hive面試題整理(二)

1、Fetch抓取

  Fetch抓取是指,Hive中對某些情況的查詢可以不必使用MapReduce計算。例如:SELECT * FROM employees;在這種情況下,Hive可以簡單地讀取employee對應的存儲目錄下的文件,然后輸出查詢結果到控制台。
  在hive-default.xml.template文件中hive.fetch.task.conversion默認是more,老版本hive默認是minimal,該屬性修改為more以后,在全局查找、字段查找、limit查找等都不走mapreduce。

2、本地模式

  大多數的Hadoop Job是需要Hadoop提供的完整的可擴展性來處理大數據集的。不過,有時Hive的輸入數據量是非常小的。在這種情況下,為查詢觸發執行任務時消耗可能會比實際job的執行時間要多的多。對於大多數這種情況,Hive可以通過本地模式在單台機器上處理所有的任務。對於小數據集,執行時間可以明顯被縮短。
  用戶可以通過設置hive.exec.mode.local.auto的值為true,來讓Hive在適當的時候自動啟動這個優化。

表的優化

3、小表、大表Join

  將key相對分散,並且數據量小的表放在join的左邊,這樣可以有效減少內存溢出錯誤發生的幾率再進一步,可以使用Group讓小的維度表(1000條以下的記錄條數)先進內存。在map端完成reduce。
  實際測試發現:新版的hive已經對小表JOIN大表和大表JOIN小表進行了優化。小表放在左邊和右邊已經沒有明顯區別。

4、大表Join大表

1)空KEY過濾
  有時join超時是因為某些key對應的數據太多,而相同key對應的數據都會發送到相同的reducer上,從而導致內存不夠。此時我們應該仔細分析這些異常的key,很多情況下,這些key對應的數據是異常數據,我們需要在SQL語句中進行過濾例如key對應的字段為空
2)空key轉換
  有時雖然某個key為空對應的數據很多,但是相應的數據不是異常數據,必須要包含在join的結果中,此時我們可以表a中key為空的字段賦一個隨機的值,使得數據隨機均勻地分不到不同的reducer上。

5、Group By

  默認情況下,Map階段同一Key數據分發給一個reduce,當一個key數據過大時就傾斜了。
  並不是所有的聚合操作都需要在Reduce端完成,很多聚合操作都可以先在Map端進行部分聚合最后在Reduce端得出最終結果。
1)開啟Map端聚合參數設置
    (1)是否在Map端進行聚合,默認為True
      hive.map.aggr = true
    (2)在Map端進行聚合操作的條目數目
      hive.groupby.mapaggr.checkinterval = 100000
    (3)有數據傾斜的時候進行負載均衡(默認是false)
      hive.groupby.skewindata = true
  當選項設定為 true,生成的查詢計划會有兩個MR Job。第一個MR Job中,Map的輸出結果會隨機分布到Reduce中,每個Reduce做部分聚合操作,並輸出結果,這樣處理的結果是相同的Group By Key有可能被分發到不同的Reduce中,從而達到負載均衡的目的;第二個MR Job再根據預處理的數據結果按照Group By Key分布到Reduce中(這個過程可以保證相同的Group By Key被分布到同一個Reduce中),最后完成最終的聚合操作。

6、Count(Distinct) 去重統計

  數據量小的時候無所謂,數據量大的情況下,由於COUNT DISTINCT操作需要用一個Reduce Task來完成,這一個Reduce需要處理的數據量太大,就會導致整個Job很難完成,一般COUNT DISTINCT使用先GROUP BY再COUNT的方式替換

7、笛卡爾積

  盡量避免笛卡爾積,join的時候不加on條件,或者無效的on條件,Hive只能使用1個reducer來完成笛卡爾積

8、行列過濾

  列處理:在SELECT中,只拿需要的列,如果有,盡量使用分區過濾,少用SELECT *
  行處理:在分區剪裁中,當使用外關聯時,如果將副表的過濾條件寫在Where后面,那么就會先全表關聯,之后再過濾。

數據傾斜

9、 Map數

1)通常情況下,作業會通過input的目錄產生一個或者多個map任務。
  主要的決定因素有:input的文件總個數,input的文件大小,集群設置的文件塊大小。
2)是不是map數越多越好?
  答案是否定的。如果一個任務有很多小文件(遠遠小於塊大小128m),則每個小文件也會被當做一個塊,用一個map任務來完成,而一個map任務啟動和初始化的時間遠遠大於邏輯處理的時間,就會造成很大的資源浪費。而且,同時可執行的map數是受限的。
3)是不是保證每個map處理接近128m的文件塊,就高枕無憂了?
  答案也是不一定。比如有一個127m的文件,正常會用一個map去完成,但這個文件只有一個或者兩個小字段,卻有幾千萬的記錄,如果map處理的邏輯比較復雜,用一個map任務去做,肯定也比較耗時。
  針對上面的問題2和3,我們需要采取兩種方式來解決:即減少map數和增加map數;

10、小文件進行合並

  在map執行前合並小文件,減少map數:CombineHiveInputFormat具有對小文件進行合並的功能(系統默認的格式)。HiveInputFormat沒有對小文件合並功能。
  set hive.input.format= org.apache.hadoop.hive.ql.io.CombineHiveInputFormat;

11、復雜文件增加Map數

  當input的文件都很大,任務邏輯復雜,map執行非常慢的時候,可以考慮增加Map數,來使得每個map處理的數據量減少,從而提高任務的執行效率。
  增加map的方法為:根據computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M公式,調整maxSize最大值。讓maxSize最大值低於blocksize可以增加map的個數。

12、Reduce數

1)調整reduce個數方法一
  (1)每個Reduce處理的數據量默認是256MB
    hive.exec.reducers.bytes.per.reducer=256000000
  (2)每個任務最大的reduce數,默認為1009
    hive.exec.reducers.max=1009
  (3)計算reducer數的公式
    N=min(參數2,總輸入數據量/參數1)
2)調整reduce個數方法二
  在hadoop的mapred-default.xml文件中修改
  設置每個job的Reduce個數
  set mapreduce.job.reduces = 15;
3)reduce個數並不是越多越好
  (1)過多的啟動和初始化reduce也會消耗時間和資源;
  (2)另外,有多少個reduce,就會有多少個輸出文件,如果生成了很多個小文件,那么如果這些小文件作為下一個任務的輸入,則也會出現小文件過多的問題;
  在設置reduce個數的時候也需要考慮這兩個原則:處理大數據量利用合適的reduce數;使單個reduce任務處理數據量大小要合適。

**==========================**

13、並行執行

  Hive會將一個查詢轉化成一個或者多個階段。這樣的階段可以是MapReduce階段、抽樣階段、合並階段、limit階段。或者Hive執行過程中可能需要的其他階段。默認情況下,Hive一次只會執行一個階段。不過,某個特定的job可能包含眾多的階段,而這些階段可能並非完全互相依賴的,也就是說有些階段是可以並行執行的,這樣可能使得整個job的執行時間縮短。不過,如果有更多的階段可以並行執行,那么job可能就越快完成。
  通過設置參數hive.exec.parallel值為true,就可以開啟並發執行。不過,在共享集群中,需要注意下,如果job中並行階段增多,那么集群利用率就會增加。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM