精選Hive高頻面試題11道,附答案詳細解析(好文收藏)

五分鐘學大資料發表於2021-07-03

1. hive內部表和外部表的區別

未被external修飾的是內部表,被external修飾的為外部表。

區別

  1. 內部表資料由Hive自身管理,外部表資料由HDFS管理;

  2. 內部表資料儲存的位置是hive.metastore.warehouse.dir(預設:/user/hive/warehouse),外部表資料的儲存位置由自己制定(如果沒有LOCATION,Hive將在HDFS上的/user/hive/warehouse資料夾下以外部表的表名建立一個資料夾,並將屬於這個表的資料存放在這裡);

  3. 刪除內部表會直接刪除後設資料(metadata)及儲存資料;刪除外部表僅僅會刪除後設資料,HDFS上的檔案並不會被刪除

本文首發於公眾號【五分鐘學大資料】

2. Hive有索引嗎

Hive支援索引(3.0版本之前),但是Hive的索引與關係型資料庫中的索引並不相同,比如,Hive不支援主鍵或者外來鍵。並且Hive索引提供的功能很有限,效率也並不高,因此Hive索引很少使用。

  • 索引適用的場景:

適用於不更新的靜態欄位。以免總是重建索引資料。每次建立、更新資料後,都要重建索引以構建索引表。

  • Hive索引的機制如下:

hive在指定列上建立索引,會產生一張索引表(Hive的一張物理表),裡面的欄位包括:索引列的值、該值對應的HDFS檔案路徑、該值在檔案中的偏移量。

Hive 0.8版本後引入bitmap索引處理器,這個處理器適用於去重後,值較少的列(例如,某欄位的取值只可能是幾個列舉值)
因為索引是用空間換時間,索引列的取值過多會導致建立bitmap索引表過大。

注意:Hive中每次有資料時需要及時更新索引,相當於重建一個新表,否則會影響資料查詢的效率和準確性,Hive官方文件已經明確表示Hive的索引不推薦被使用,在新版本的Hive中已經被廢棄了

擴充套件:Hive是在0.7版本之後支援索引的,在0.8版本後引入bitmap索引處理器,在3.0版本開始移除索引的功能,取而代之的是2.3版本開始的物化檢視,自動重寫的物化檢視替代了索引的功能。

3. 運維如何對hive進行排程

  1. 將hive的sql定義在指令碼當中;

  2. 使用azkaban或者oozie進行任務的排程;

  3. 監控任務排程頁面。

4. ORC、Parquet等列式儲存的優點

ORC和Parquet都是高效能的儲存方式,這兩種儲存格式總會帶來儲存和效能上的提升。

Parquet:

  1. Parquet支援巢狀的資料模型,類似於Protocol Buffers,每一個資料模型的schema包含多個欄位,每一個欄位有三個屬性:重複次數、資料型別和欄位名。
    重複次數可以是以下三種:required(只出現1次),repeated(出現0次或多次),optional(出現0次或1次)。每一個欄位的資料型別可以分成兩種:
    group(複雜型別)和primitive(基本型別)。

  2. Parquet中沒有Map、Array這樣的複雜資料結構,但是可以通過repeated和group組合來實現的。

  3. 由於Parquet支援的資料模型比較鬆散,可能一條記錄中存在比較深的巢狀關係,如果為每一條記錄都維護一個類似的樹狀結可能會佔用較大的儲存空間,因此Dremel論文中提出了一種高效的對於巢狀資料格式的壓縮演算法:Striping/Assembly演算法。通過Striping/Assembly演算法,parquet可以使用較少的儲存空間表示複雜的巢狀格式,並且通常Repetition level和Definition level都是較小的整數值,可以通過RLE演算法對其進行壓縮,進一步降低儲存空間。

  4. Parquet檔案是以二進位制方式儲存的,是不可以直接讀取和修改的,Parquet檔案是自解析的,檔案中包括該檔案的資料和後設資料。

ORC:

  1. ORC檔案是自描述的,它的後設資料使用Protocol Buffers序列化,並且檔案中的資料儘可能的壓縮以降低儲存空間的消耗。

  2. 和Parquet類似,ORC檔案也是以二進位制方式儲存的,所以是不可以直接讀取,ORC檔案也是自解析的,它包含許多的後設資料,這些後設資料都是同構ProtoBuffer進行序列化的。

  3. ORC會盡可能合併多個離散的區間儘可能的減少I/O次數。

  4. ORC中使用了更加精確的索引資訊,使得在讀取資料時可以指定從任意一行開始讀取,更細粒度的統計資訊使得讀取ORC檔案跳過整個row group,ORC預設會對任何一塊資料和索引資訊使用ZLIB壓縮,因此ORC檔案佔用的儲存空間也更小。

  5. 在新版本的ORC中也加入了對Bloom Filter的支援,它可以進一
    步提升謂詞下推的效率,在Hive 1.2.0版本以後也加入了對此的支
    持。

5. 資料建模用的哪些模型?

1. 星型模型

星形模式

星形模式(Star Schema)是最常用的維度建模方式。星型模式是以事實表為中心,所有的維度表直接連線在事實表上,像星星一樣。
星形模式的維度建模由一個事實表和一組維表成,且具有以下特點:

a. 維表只和事實表關聯,維表之間沒有關聯;

b. 每個維表主鍵為單列,且該主鍵放置在事實表中,作為兩邊連線的外來鍵;

c. 以事實表為核心,維表圍繞核心呈星形分佈。

2. 雪花模型

雪花模式

雪花模式(Snowflake Schema)是對星形模式的擴充套件。雪花模式的維度表可以擁有其他維度表的,雖然這種模型相比星型更規範一些,但是由於這種模型不太容易理解,維護成本比較高,而且效能方面需要關聯多層維表,效能比星型模型要低。

3. 星座模型

星座模型

星座模式是星型模式延伸而來,星型模式是基於一張事實表的,而星座模式是基於多張事實表的,而且共享維度資訊。前面介紹的兩種維度建模方法都是多維表對應單事實表,但在很多時候維度空間內的事實表不止一個,而一個維表也可能被多個事實表用到。在業務發展後期,絕大部分維度建模都採用的是星座模式。

數倉建模詳細介紹可檢視:通俗易懂數倉建模

6. 為什麼要對資料倉儲分層?

  • 用空間換時間,通過大量的預處理來提升應用系統的使用者體驗(效率),因此資料倉儲會存在大量冗餘的資料。

  • 如果不分層的話,如果源業務系統的業務規則發生變化將會影響整個資料清洗過程,工作量巨大。

  • 通過資料分層管理可以簡化資料清洗的過程,因為把原來一步的工作分到了多個步驟去完成,相當於把一個複雜的工作拆成了多個簡單的工作,把一個大的黑盒變成了一個白盒,每一層的處理邏輯都相對簡單和容易理解,這樣我們比較容易保證每一個步驟的正確性,當資料發生錯誤的時候,往往我們只需要區域性調整某個步驟即可。

資料倉儲詳細介紹可檢視:萬字詳解整個資料倉儲建設體系

7. 使用過Hive解析JSON串嗎

Hive處理json資料總體來說有兩個方向的路走

  1. 將json以字串的方式整個入Hive表,然後通過使用UDF函式解析已經匯入到hive中的資料,比如使用LATERAL VIEW json_tuple的方法,獲取所需要的列名。

  2. 在匯入之前將json拆成各個欄位,匯入Hive表的資料是已經解析過的。這將需要使用第三方的
    SerDe。

詳細介紹可檢視:Hive解析Json陣列超全講解

8. sort by 和 order by 的區別

order by 會對輸入做全域性排序,因此只有一個reducer(多個reducer無法保證全域性有序)只有一個reducer,會導致當輸入規模較大時,需要較長的計算時間。

sort by不是全域性排序,其在資料進入reducer前完成排序.
因此,如果用sort by進行排序,並且設定mapred.reduce.tasks>1, 則sort by只保證每個reducer的輸出有序,不保證全域性有序

9. 資料傾斜怎麼解決

資料傾斜問題主要有以下幾種:

  1. 空值引發的資料傾斜

  2. 不同資料型別引發的資料傾斜

  3. 不可拆分大檔案引發的資料傾斜

  4. 資料膨脹引發的資料傾斜

  5. 表連線時引發的資料傾斜

  6. 確實無法減少資料量引發的資料傾斜

以上傾斜問題的具體解決方案可檢視:Hive千億級資料傾斜解決方案

注意:對於 left join 或者 right join 來說,不會對關聯的欄位自動去除null值,對於 inner join 來說,會對關聯的欄位自動去除null值。

小夥伴們在閱讀時注意下,在上面的文章(Hive千億級資料傾斜解決方案)中,有一處sql出現了上述問題(舉例的時候原本是想使用left join的,結果手誤寫成了join)。此問題由公眾號讀者發現,感謝這位讀者指正。

10. Hive 小檔案過多怎麼解決

1. 使用 hive 自帶的 concatenate 命令,自動合併小檔案

使用方法:

#對於非分割槽表
alter table A concatenate;

#對於分割槽表
alter table B partition(day=20201224) concatenate;

注意:
1、concatenate 命令只支援 RCFILE 和 ORC 檔案型別。
2、使用concatenate命令合併小檔案時不能指定合併後的檔案數量,但可以多次執行該命令。
3、當多次使用concatenate後檔案數量不在變化,這個跟引數 mapreduce.input.fileinputformat.split.minsize=256mb 的設定有關,可設定每個檔案的最小size。

2. 調整引數減少Map數量

設定map輸入合併小檔案的相關引數(執行Map前進行小檔案合併):

在mapper中將多個檔案合成一個split作為輸入(CombineHiveInputFormat底層是Hadoop的CombineFileInputFormat方法):

set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; -- 預設

每個Map最大輸入大小(這個值決定了合併後檔案的數量):

set mapred.max.split.size=256000000;   -- 256M

一個節點上split的至少大小(這個值決定了多個DataNode上的檔案是否需要合併):

set mapred.min.split.size.per.node=100000000;  -- 100M

一個交換機下split的至少大小(這個值決定了多個交換機上的檔案是否需要合併):

set mapred.min.split.size.per.rack=100000000;  -- 100M
3. 減少Reduce的數量

reduce 的個數決定了輸出的檔案的個數,所以可以調整reduce的個數控制hive表的檔案數量。

hive中的分割槽函式 distribute by 正好是控制MR中partition分割槽的,可以通過設定reduce的數量,結合分割槽函式讓資料均衡的進入每個reduce即可:

#設定reduce的數量有兩種方式,第一種是直接設定reduce個數
set mapreduce.job.reduces=10;

#第二種是設定每個reduce的大小,Hive會根據資料總大小猜測確定一個reduce個數
set hive.exec.reducers.bytes.per.reducer=5120000000; -- 預設是1G,設定為5G

#執行以下語句,將資料均衡的分配到reduce中
set mapreduce.job.reduces=10;
insert overwrite table A partition(dt)
select * from B
distribute by rand();

對於上述語句解釋:如設定reduce數量為10,使用 rand(), 隨機生成一個數 x % 10
這樣資料就會隨機進入 reduce 中,防止出現有的檔案過大或過小。

4. 使用hadoop的archive將小檔案歸檔

Hadoop Archive簡稱HAR,是一個高效地將小檔案放入HDFS塊中的檔案存檔工具,它能夠將多個小檔案打包成一個HAR檔案,這樣在減少namenode記憶體使用的同時,仍然允許對檔案進行透明的訪問。

#用來控制歸檔是否可用
set hive.archive.enabled=true;
#通知Hive在建立歸檔時是否可以設定父目錄
set hive.archive.har.parentdir.settable=true;
#控制需要歸檔檔案的大小
set har.partfile.size=1099511627776;

使用以下命令進行歸檔:
ALTER TABLE A ARCHIVE PARTITION(dt='2021-05-07', hr='12');

對已歸檔的分割槽恢復為原檔案:
ALTER TABLE A UNARCHIVE PARTITION(dt='2021-05-07', hr='12');

注意:
歸檔的分割槽可以檢視不能 insert overwrite,必須先 unarchive

Hive 小檔案問題具體可檢視:解決hive小檔案過多問題

11. Hive優化有哪些

1. 資料儲存及壓縮:

針對hive中表的儲存格式通常有orc和parquet,壓縮格式一般使用snappy。相比與textfile格式表,orc佔有更少的儲存。因為hive底層使用MR計算架構,資料流是hdfs到磁碟再到hdfs,而且會有很多次,所以使用orc資料格式和snappy壓縮策略可以降低IO讀寫,還能降低網路傳輸量,這樣在一定程度上可以節省儲存,還能提升hql任務執行效率;

2. 通過調參優化:

並行執行,調節parallel引數;

調節jvm引數,重用jvm;

設定map、reduce的引數;開啟strict mode模式;

關閉推測執行設定。

3. 有效地減小資料集將大表拆分成子表;結合使用外部表和分割槽表。
4. SQL優化
  • 大表對大表:儘量減少資料集,可以通過分割槽表,避免掃描全表或者全欄位;

  • 大表對小表:設定自動識別小表,將小表放入記憶體中去執行。

Hive優化詳細剖析可檢視:Hive企業級效能優化


--END--

相關文章