Hive面試題——持續更新
Hive
Hive之不需要分散式安裝 hive相當於hadoop客戶端,hive工作職責把sql語句轉化為Mapreduce,然後在hadoop叢集上執行 Hive架構簡介: HDFS:用來儲存hive倉庫的資料檔案 yarn:用來完成hive的HQL轉化的MR程式的執行 MetaStore:儲存管理hive維護的元資料 Hive:用來通過HQL的執行,轉化為MapReduce程式的執行,從而對HDFS叢集中的資料檔案進行統計。 Hive架構解析 hive這個軟體不能獨立自主存在,存在hive裡的資料本質存在hdfs裡面,hive裡面的sql語句,最終轉換為mapreduce交給yarn資源排程器執行。sql語句轉mapreduce時有一些不能確定的因素,表路徑,列與檔案裡面欄位的對映這些元資料會存在MetaStore裡面。 分散式不一定是叢集,但是叢集一定是分散式 Hive在執行SQL底層轉換成mapreduce(日誌資訊中可以看出來)
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-v8f5IZU0-1612053529408)(C:\Users\39217\Desktop\大資料面試題\大資料面試題.assets\image-20201229153625253.png)]
hive的兩種啟動方式
1,本地模式啟動(管理員模式)
hive
啟動伺服器,同時進入hive客戶端
2,hive的客戶端和服務端
先啟動hive伺服器,可以允許遠端訪問。
hiveserver 2 &
再啟動客戶端
[[email protected] ~]# beeline beeline> !connect jdbc:hive2://hadoop10:10000 回車輸入mysql使用者名稱 回車輸入mysql密碼
hive執行流程
hive主要是通過將使用者書寫的SQL語句翻譯成MapReduce程式碼,然後釋出任務給MR框架執行,完成SQL 到 MapReduce的轉換。可以將結構化的資料檔案對映為一張資料庫表,並提供類SQL查詢功能。可以實現資料的檢視;
hive中的資料匯入
1,建表,根據資料結構定義分割符(正常使用的三種分割符:自定義,json,正則分隔符)
2,通過口令執行把資料(本地/hdfs)新增到我們建立的表裡
SQL執行順序
from > where條件 > group by > having條件>select>order by>limit
hive中存放的是什麼?
存的是和hdfs的對映關係,hive是邏輯上的資料倉庫,實際操作的都是hdfs上的檔案,HQL就是用SQL
語法來寫的MR程式。
Hive與關係型資料庫的關係?
沒有關係,hive是資料倉庫,不能和資料庫一樣進行實時的CRUD操作。
是一次寫入多次讀取的操作,可以看成是ETL的工具。
請說明hive中Sort By、Order By、Cluster By,Distribute By各代表什麼意思?
order by:會對資料做全域性排序,因此只有一個reducer(多個reducer無法保證全域性有序)。只有一個reducer,會導致當輸入規模較大時,需要較長的計算時間。
sort by:不是全域性排序,其在資料進入reducer前完成排序。
distribute by:按照指定的欄位對資料進行劃分輸出到不同的reduce中。
cluster by:除了具有 distribute by 的功能外還兼具 sort by 的功能。
hive中的炸裂函式
炸裂函式(集合函式):一行變多行,比如數倉專案,event(事件)日誌,因為為多個事件所以就是一個集合,集合裡面是多個json物件,通過我們自定義的炸裂函式把一個even事件陣列炸裂成多行。
Hive表分類
——hive中允許先有資料後有表;
管理表:當用戶刪除表的同時,hive也會將表所對應的資料刪除
外部表:外部表和管理表最大的區別在於刪除外部表,只是將MySQL中對應該表的元資料資訊刪除,並不會刪除hdfs上的資料
分割槽表:將表按照某個列的一定規則進行分割槽存放,減少海量資料情況下的資料檢索範圍,提高查詢效率;
Hive自定義UDF、UDTF
自定義UDF:
-
必須繼承UDF
-
方法名必須是evaluate(此方法名底層固定不能修改)
-
上傳linux,通過口令新增:add jar /opt/doc/funcHello.jar;
自定義UDTF:繼承GenericUDTF
udf:使用者自定義單行函式
udaf:使用者自定義聚合函式
udtf:使用者自定義炸裂函式
自定義UDF、UDTF
在專案中是否自定義過UDF、UDTF函式,以及用他們處理了什麼問題,及自定義步驟?
用UDF函式解析公共欄位;用UDTF函式解析事件欄位。
自定義UDF:繼承UDF,重寫evaluate方法
自定義UDTF:繼承自GenericUDTF,重寫3個方法:initialize(自定義輸出的列名和型別),
process(將結果返回forward(result)),close
為什麼要自定義UDF/UDTF,因為自定義函式,可以自己埋點Log列印日誌,出錯或者資料異常,方便
除錯.
Hive優化
1)MapJoin
如果不指定MapJoin或者不符合MapJoin的條件,那麼Hive解析器會將Join操作轉換成Common Join,即:在Reduce階段完成join。容易發生資料傾斜。可以用MapJoin把小表全部載入到記憶體在map端進行join,避免reducer處理。
2)行列過濾
列處理:在SELECT中,只拿需要的列,如果有,儘量使用分割槽過濾,少用SELECT *。
行處理:在分割槽剪裁中,當使用外關聯時,如果將副表的過濾條件寫在Where後面,那麼就會先全表關聯,之後再過濾。
3)列式儲存
4)採用分割槽技術
5)合理設定Map數
(1)通常情況下,作業會通過input的目錄產生一個或者多個map任務。
主要的決定因素有:input的檔案總個數,input的檔案大小,叢集設定的檔案塊大小。
(2)是不是map數越多越好?
答案是否定的。如果一個任務有很多小檔案(遠遠小於塊大小128m),則每個小檔案也會被當做一個塊,用一個map任務來完成,而一個map任務啟動和初始化的時間遠遠大於邏輯處理的時間,就會造成很大的資源浪費。而且,同時可執行的map數是受限的。
(3)是不是保證每個map處理接近128m的檔案塊,就高枕無憂了?
答案也是不一定。比如有一個127m的檔案,正常會用一個map去完成,但這個檔案只有一個或者兩個小欄位,卻有幾千萬的記錄,如果map處理的邏輯比較複雜,用一個map任務去做,肯定也比較耗時。
針對上面的問題2和3,我們需要採取兩種方式來解決:即減少map數和增加map數;
6)小檔案進行合併
在Map執行前合併小檔案,減少Map數:CombineHiveInputFormat具有對小檔案進行合併的功能(系統預設的格式)。HiveInputFormat沒有對小檔案合併功能。
7)合理設定Reduce數
Reduce個數並不是越多越好
(1)過多的啟動和初始化Reduce也會消耗時間和資源;
(2)另外,有多少個Reduce,就會有多少個輸出檔案,如果生成了很多個小檔案,那麼如果這些小檔案作為下一個任務的輸入,則也會出現小檔案過多的問題;
在設定Reduce個數的時候也需要考慮這兩個原則:處理大資料量利用合適的Reduce數;使單個Reduce任務處理資料量大小要合適;
8)常用引數
// 輸出合併小檔案
SET hive.merge.mapfiles = true; – 預設true,在map-only任務結束時合併小檔案
SET hive.merge.mapredfiles = true; – 預設false,在map-reduce任務結束時合併小檔案
SET hive.merge.size.per.task = 268435456; – 預設256M
SET hive.merge.smallfiles.avgsize = 16777216; – 當輸出檔案的平均大小小於16m該值時,啟動一個獨立的map-reduce任務進行檔案merge
9)開啟map端combiner(不影響最終業務邏輯)
set hive.map.aggr=true;
10)壓縮(選擇快的)
設定map端輸出、中間結果壓縮。(不完全是解決資料傾斜的問題,但是減少了IO讀寫和網路傳輸,能提高很多效率)
11)開啟JVM重用
靜態分割槽和動態分割槽
a. 靜態分割槽與動態分割槽的主要區別在於靜態分割槽是手動指定,而動態分割槽是通過資料來進行判斷。
b. 詳細來說,靜態分割槽的列實在編譯時期,通過使用者傳遞來決定的;動態分割槽只有在 SQL 執行時才能決定。
c. 動態分割槽是基於查詢引數的位置去推斷分割槽的名稱,從而建立分割槽
開窗函式
開窗函式簡介:與聚合函式一樣,開窗函式也是對行集組進行聚合計算,但是它不像普通聚合函式那樣每組只返回一個值,開窗函式可以為每組返回多個值,因為開窗函式所執行聚合計算的行集組是視窗。在 ISO SQL 規定了這樣的函式為開窗函式,在 Oracle 中則被稱為分析函式。
開窗函式格式: 函式名(列) OVER(選項)
函式名([列]) over( [partition by 欄位] [order by 欄位 desc|asc] )
函式名:聚合函式、排序函式等函式
OVER 關鍵字表示把函式當成開窗函式而不是聚合函式。SQL 標準允許將所有聚合函式用做開窗函式,使用 OVER 關鍵字來區分這兩種用法。
如果 OVER 關鍵字後的括號中的選項為空,則開窗函式會對結果集中的所有行進行聚合運算。
PARTITION BY 子句:
開窗函式的 OVER 關鍵字後括號中的可以使用 PARTITION BY 子句來定義行的分割槽來供進行聚合計算。與 GROUP BY 子句不同,PARTITION BY 子句建立的分割槽是獨立於結果集的
(HDFS頁面會有檔案是根據分割槽分別儲存),建立的分割槽只是供進行聚合計算的,而且不同的開窗函式所建立的分割槽也不互相影響
ORDER BY子句:
開窗函式中可以在OVER關鍵字後的選項中使用ORDER BY子句來指定排序規則,而且有的開窗函式還要求必須指定排序規則。使用ORDER BY子句可以對結果集按照指定的排序規則進行排序,並且在一個指定的範圍內進行聚合運算
hive分桶的原理
跟MR中的HashPartitioner的原理一模一樣
MR中:按照key的hash值去模除以reductTask的個數
Hive中:按照分桶欄位的hash值去模除以分桶的個數
分桶的好處:
1、方便抽樣
2、提高join(連線)查詢效率
分桶表和分割槽表的 桶數 和 分割槽數的 決定機制:
分桶表的個數:由使用者的HQL語句所設定的reduceTask的個數決定
表的分割槽的個數:也能由使用者自定義指定。也能由程式自動生成, 分割槽是可以動態增長的
分桶表和分割槽表的個數的區別:
分桶表是一經決定,就不能更改,所以如果要改變桶數,要重新插入分桶資料
分割槽數是可以動態增長的,log日誌,一天存一個分割槽
分桶表和分割槽表中資料的表現:
1、分桶表中的每個分桶中的資料可以有多個key值
2、分割槽表中的每個分割槽只有一個 key值