大數(shù)據(jù)面試-hive篇

1. Hive內(nèi)部表和外部表的區(qū)別

未被external修飾的是內(nèi)部表,被external修飾的為外部表。

區(qū)別

  1. 內(nèi)部表數(shù)據(jù)由Hive自身管理,外部表數(shù)據(jù)由HDFS管理;

  2. 內(nèi)部表數(shù)據(jù)存儲的位置是hive.metastore.warehouse.dir(默認:/user/hive/warehouse),外部表數(shù)據(jù)的存儲位置由自己制定(如果沒有LOCATION,Hive將在HDFS上的/user/hive/warehouse文件夾下以外部表的表名創(chuàng)建一個文件夾,并將屬于這個表的數(shù)據(jù)存放在這里);

  3. 刪除內(nèi)部表會直接刪除元數(shù)據(jù)(metadata)及存儲數(shù)據(jù);刪除外部表僅僅會刪除元數(shù)據(jù),HDFS上的文件并不會被刪除。

2. Hive有索引嗎

Hive支持索引(3.0版本之前),但是Hive的索引與關(guān)系型數(shù)據(jù)庫中的索引并不相同,比如,Hive不支持主鍵或者外鍵。并且Hive索引提供的功能很有限,效率也并不高,因此Hive索引很少使用。

  • 索引適用的場景:

適用于不更新的靜態(tài)字段。以免總是重建索引數(shù)據(jù)。每次建立、更新數(shù)據(jù)后,都要重建索引以構(gòu)建索引表。

  • Hive索引的機制如下:

hive在指定列上建立索引,會產(chǎn)生一張索引表(Hive的一張物理表),里面的字段包括:索引列的值、該值對應(yīng)的HDFS文件路徑、該值在文件中的偏移量。

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

注意:Hive中每次有數(shù)據(jù)時需要及時更新索引,相當(dāng)于重建一個新表,否則會影響數(shù)據(jù)查詢的效率和準確性,Hive官方文檔已經(jīng)明確表示Hive的索引不推薦被使用,在新版本的Hive中已經(jīng)被廢棄了。

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

3. 運維如何對Hive進行調(diào)度

  1. 將hive的sql定義在腳本當(dāng)中;

  2. 使用azkaban或者oozie進行任務(wù)的調(diào)度;

  3. 監(jiān)控任務(wù)調(diào)度頁面。

4. ORC、Parquet等列式存儲的優(yōu)點

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

Parquet:

  1. Parquet支持嵌套的數(shù)據(jù)模型,類似于Protocol Buffers,每一個數(shù)據(jù)模型的schema包含多個字段,每一個字段有三個屬性:重復(fù)次數(shù)、數(shù)據(jù)類型和字段名。
    重復(fù)次數(shù)可以是以下三種:required(只出現(xiàn)1次),repeated(出現(xiàn)0次或多次),optional(出現(xiàn)0次或1次)。每一個字段的數(shù)據(jù)類型可以分成兩種: group(復(fù)雜類型)和primitive(基本類型)。

  2. Parquet中沒有Map、Array這樣的復(fù)雜數(shù)據(jù)結(jié)構(gòu),但是可以通過repeated和group組合來實現(xiàn)的。

  3. 由于Parquet支持的數(shù)據(jù)模型比較松散,可能一條記錄中存在比較深的嵌套關(guān)系,如果為每一條記錄都維護一個類似的樹狀結(jié)可能會占用較大的存儲空間,因此Dremel論文中提出了一種高效的對于嵌套數(shù)據(jù)格式的壓縮算法:Striping/Assembly算法。通過Striping/Assembly算法,parquet可以使用較少的存儲空間表示復(fù)雜的嵌套格式,并且通常Repetition level和Definition level都是較小的整數(shù)值,可以通過RLE算法對其進行壓縮,進一步降低存儲空間。

  4. Parquet文件是以二進制方式存儲的,是不可以直接讀取和修改的,Parquet文件是自解析的,文件中包括該文件的數(shù)據(jù)和元數(shù)據(jù)。

ORC:

  1. ORC文件是自描述的,它的元數(shù)據(jù)使用Protocol Buffers序列化,并且文件中的數(shù)據(jù)盡可能的壓縮以降低存儲空間的消耗。

  2. 和Parquet類似,ORC文件也是以二進制方式存儲的,所以是不可以直接讀取,ORC文件也是自解析的,它包含許多的元數(shù)據(jù),這些元數(shù)據(jù)都是同構(gòu)ProtoBuffer進行序列化的。

  3. ORC會盡可能合并多個離散的區(qū)間盡可能的減少I/O次數(shù)。

  4. ORC中使用了更加精確的索引信息,使得在讀取數(shù)據(jù)時可以指定從任意一行開始讀取,更細粒度的統(tǒng)計信息使得讀取ORC文件跳過整個row group,ORC默認會對任何一塊數(shù)據(jù)和索引信息使用ZLIB壓縮,因此ORC文件占用的存儲空間也更小。

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

5. 數(shù)據(jù)建模用的哪些模型?

1. 星型模型
微信圖片_20230314125445.png

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

a. 維表只和事實表關(guān)聯(lián),維表之間沒有關(guān)聯(lián);

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

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

2. 雪花模型
微信圖片_20230314125455.png

雪花模式(Snowflake Schema)是對星形模式的擴展。雪花模式的維度表可以擁有其他維度表的,雖然這種模型相比星型更規(guī)范一些,但是由于這種模型不太容易理解,維護成本比較高,而且性能方面需要關(guān)聯(lián)多層維表,性能比星型模型要低。

3. 星座模型
微信圖片_20230314125507.png

星座模式是星型模式延伸而來,星型模式是基于一張事實表的,而星座模式是基于多張事實表的,而且共享維度信息。前面介紹的兩種維度建模方法都是多維表對應(yīng)單事實表,但在很多時候維度空間內(nèi)的事實表不止一個,而一個維表也可能被多個事實表用到。在業(yè)務(wù)發(fā)展后期,絕大部分維度建模都采用的是星座模式。

數(shù)倉建模詳細介紹可查看:通俗易懂?dāng)?shù)倉建模

6. 為什么要對數(shù)據(jù)倉庫分層?

  • 用空間換時間,通過大量的預(yù)處理來提升應(yīng)用系統(tǒng)的用戶體驗(效率),因此數(shù)據(jù)倉庫會存在大量冗余的數(shù)據(jù)。

  • 如果不分層的話,如果源業(yè)務(wù)系統(tǒng)的業(yè)務(wù)規(guī)則發(fā)生變化將會影響整個數(shù)據(jù)清洗過程,工作量巨大。

  • 通過數(shù)據(jù)分層管理可以簡化數(shù)據(jù)清洗的過程,因為把原來一步的工作分到了多個步驟去完成,相當(dāng)于把一個復(fù)雜的工作拆成了多個簡單的工作,把一個大的黑盒變成了一個白盒,每一層的處理邏輯都相對簡單和容易理解,這樣我們比較容易保證每一個步驟的正確性,當(dāng)數(shù)據(jù)發(fā)生錯誤的時候,往往我們只需要局部調(diào)整某個步驟即可。

數(shù)據(jù)倉庫詳細介紹可查看:萬字詳解整個數(shù)據(jù)倉庫建設(shè)體系

7. 使用過Hive解析JSON串嗎

Hive處理json數(shù)據(jù)總體來說有兩個方向的路走

  1. 將json以字符串的方式整個入Hive表,然后通過使用UDF函數(shù)解析已經(jīng)導(dǎo)入到hive中的數(shù)據(jù),比如使用LATERAL VIEW json_tuple的方法,獲取所需要的列名。

  2. 在導(dǎo)入之前將json拆成各個字段,導(dǎo)入Hive表的數(shù)據(jù)是已經(jīng)解析過的。這將需要使用第三方的 SerDe。

詳細介紹可查看:Hive解析Json數(shù)組超全講解

8. sort by 和 order by 的區(qū)別

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

sort by不是全局排序,其在數(shù)據(jù)進入reducer前完成排序. 因此,如果用sort by進行排序,并且設(shè)置mapred.reduce.tasks>1, 則sort by只保證每個reducer的輸出有序,不保證全局有序。

9. 數(shù)據(jù)傾斜怎么解決

數(shù)據(jù)傾斜問題主要有以下幾種:

  1. 空值引發(fā)的數(shù)據(jù)傾斜

  2. 不同數(shù)據(jù)類型引發(fā)的數(shù)據(jù)傾斜

  3. 不可拆分大文件引發(fā)的數(shù)據(jù)傾斜

  4. 數(shù)據(jù)膨脹引發(fā)的數(shù)據(jù)傾斜

  5. 表連接時引發(fā)的數(shù)據(jù)傾斜

  6. 確實無法減少數(shù)據(jù)量引發(fā)的數(shù)據(jù)傾斜

以上傾斜問題的具體解決方案可查看:Hive千億級數(shù)據(jù)傾斜解決方案

注意:對于 left join 或者 right join 來說,不會對關(guān)聯(lián)的字段自動去除null值,對于 inner join 來說,會對關(guān)聯(lián)的字段自動去除null值。

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

10. Hive 小文件過多怎么解決

1. 使用 hive 自帶的 concatenate 命令,自動合并小文件

使用方法:

#對于非分區(qū)表alter table A concatenate;#對于分區(qū)表alter table B partition(day=20201224) concatenate;

注意:
1、concatenate 命令只支持 RCFILE 和 ORC 文件類型。
2、使用concatenate命令合并小文件時不能指定合并后的文件數(shù)量,但可以多次執(zhí)行該命令。
3、當(dāng)多次使用concatenate后文件數(shù)量不在變化,這個跟參數(shù) mapreduce.input.fileinputformat.split.minsize=256mb 的設(shè)置有關(guān),可設(shè)定每個文件的最小size。

2. 調(diào)整參數(shù)減少Map數(shù)量

設(shè)置map輸入合并小文件的相關(guān)參數(shù)(執(zhí)行Map前進行小文件合并):

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

set hive.input.format=org.apache.hadoop.hive.ql.io.CombineHiveInputFormat; -- 默認

每個Map最大輸入大小(這個值決定了合并后文件的數(shù)量):

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

一個節(jié)點上split的至少大?。ㄟ@個值決定了多個DataNode上的文件是否需要合并):

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

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

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

reduce 的個數(shù)決定了輸出的文件的個數(shù),所以可以調(diào)整reduce的個數(shù)控制hive表的文件數(shù)量。

hive中的分區(qū)函數(shù) distribute by 正好是控制MR中partition分區(qū)的,可以通過設(shè)置reduce的數(shù)量,結(jié)合分區(qū)函數(shù)讓數(shù)據(jù)均衡的進入每個reduce即可:

#設(shè)置reduce的數(shù)量有兩種方式,第一種是直接設(shè)置reduce個數(shù)set mapreduce.job.reduces=10;#第二種是設(shè)置每個reduce的大小,Hive會根據(jù)數(shù)據(jù)總大小猜測確定一個reduce個數(shù)set hive.exec.reducers.bytes.per.reducer=5120000000; -- 默認是1G,設(shè)置為5G#執(zhí)行以下語句,將數(shù)據(jù)均衡的分配到reduce中set mapreduce.job.reduces=10;insert overwrite table A partition(dt)select * from Bdistribute by rand();

對于上述語句解釋:如設(shè)置reduce數(shù)量為10,使用 rand(), 隨機生成一個數(shù) x % 10 , 這樣數(shù)據(jù)就會隨機進入 reduce 中,防止出現(xiàn)有的文件過大或過小。

4. 使用hadoop的archive將小文件歸檔

Hadoop Archive簡稱HAR,是一個高效地將小文件放入HDFS塊中的文件存檔工具,它能夠?qū)⒍鄠€小文件打包成一個HAR文件,這樣在減少namenode內(nèi)存使用的同時,仍然允許對文件進行透明的訪問。

#用來控制歸檔是否可用set hive.archive.enabled=true;#通知Hive在創(chuàng)建歸檔時是否可以設(shè)置父目錄set hive.archive.har.parentdir.settable=true;#控制需要歸檔文件的大小set har.partfile.size=1099511627776;使用以下命令進行歸檔:ALTER TABLE A ARCHIVE PARTITION(dt='2021-05-07', hr='12');對已歸檔的分區(qū)恢復(fù)為原文件:ALTER TABLE A UNARCHIVE PARTITION(dt='2021-05-07', hr='12');

注意:
歸檔的分區(qū)可以查看不能 insert overwrite,必須先 unarchive

Hive 小文件問題具體可查看:解決hive小文件過多問題

11. Hive優(yōu)化有哪些

1. 數(shù)據(jù)存儲及壓縮:

針對hive中表的存儲格式通常有orc和parquet,壓縮格式一般使用snappy。相比與textfile格式表,orc占有更少的存儲。因為hive底層使用MR計算架構(gòu),數(shù)據(jù)流是hdfs到磁盤再到hdfs,而且會有很多次,所以使用orc數(shù)據(jù)格式和snappy壓縮策略可以降低IO讀寫,還能降低網(wǎng)絡(luò)傳輸量,這樣在一定程度上可以節(jié)省存儲,還能提升hql任務(wù)執(zhí)行效率;

2. 通過調(diào)參優(yōu)化:

并行執(zhí)行,調(diào)節(jié)parallel參數(shù);

調(diào)節(jié)jvm參數(shù),重用jvm;

設(shè)置map、reduce的參數(shù);開啟strict mode模式;

關(guān)閉推測執(zhí)行設(shè)置。

3. 有效地減小數(shù)據(jù)集將大表拆分成子表;結(jié)合使用外部表和分區(qū)表。
4. SQL優(yōu)化
  • 大表對大表:盡量減少數(shù)據(jù)集,可以通過分區(qū)表,避免掃描全表或者全字段;

  • 大表對小表:設(shè)置自動識別小表,將小表放入內(nèi)存中去執(zhí)行。

Hive優(yōu)化詳細剖析可查看:Hive企業(yè)級性能優(yōu)化

12. Tez引擎優(yōu)點?

Tez可以將多個有依賴的作業(yè)轉(zhuǎn)換為一個作業(yè),這樣只需寫一次HDFS,且中間節(jié)點較少,從而大大提升作業(yè)的計算性能。

Mr/tez/spark區(qū)別:

Mr引擎:多job串聯(lián),基于磁盤,落盤的地方比較多。雖然慢,但一定能跑出結(jié)果。一般處理,周、月、年指標

Spark引擎:雖然在Shuffle過程中也落盤,但是并不是所有算子都需要Shuffle,尤其是多算子過程,中間過程不落盤 DAG有向無環(huán)圖。 兼顧了可靠性和效率。一般處理天指標。

Tez引擎:完全基于內(nèi)存。 注意:如果數(shù)據(jù)量特別大,慎重使用。容易OOM。一般用于快速出結(jié)果,數(shù)據(jù)量比較小的場景。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容