大數據技術之_32_大數據面試題_01_Hive 基本面試 + Hive 數據分析面試 + Flume + Kafka 面試

一、Hive 基本面試

1、什麼是 metastore

  metadata 即元數據。包含 database、tabel、column names、partitions 信息、bucketing 信息等的元數據信息。
  元數據默認是存儲在 Derby 中,建議存儲在關係型數據庫中。

2、metastore 安裝方式有什麼區別

內嵌模式
  內嵌模式使用的是內嵌的 Derby 數據庫來存儲元數據,也不需要額外起 Metastore 服務。這個是默認的,配置簡單,但是一次只能一個客戶端連接,適用於用來實驗,不適用於生產環境。

本地元存儲
  本地安裝 mysql 替代 derby 存儲元數據,這種安裝方式和嵌入式的區別在於,不再使用內嵌的 Derby 作爲元數據的存儲介質,而是使用其他數據庫比如 MySQL 來存儲元數據。hive 服務和 metastore 服務運行在同一個進程中,mysql 是單獨的進程,可以同一臺機器,也可以在遠程機器上。

遠程元存儲(HiveServer2)
  Hive 服務和 metastore 在不同的進程內,可能是不同的機器,該模式需要將 hive.metastore.uris 設置爲 metastore 服務器 URL,如果有多個 metastore 服務器,將 URL 之間用逗號分隔,metastore 服務器 URL 的格式爲 thrift://127.0.0.1:9083。

3、什麼是 Managed Table 跟 External Table?

  • 1、Hive 有兩種類型的表 Managed Table(內部表) 跟 External Table(外部表)。
  • 2、Managed Table:也被稱作 Internal table,這種表是 hive 的默認類型。如果你在創建表的時候沒有指明 Managed 或者 External,那麼默認就會給你創建 Managed Table。
      a、Managed Table 的數據,會存放在 HDFS 中的特定的位置中,通常是 /user/username/hive/warehouse
      b、我們可以使用 describe formatted table_name; 命令來查看錶的信息。
      c、當你刪除 drop table table_name; 刪除表時,數據文件也會一併刪除。
  • 3、External Table:特別適用於想要在 Hive 之外使用表的數據的情況.當你刪除 External Table 時,只是刪除了表的元數據,它的數據並沒有被刪除。

4、什麼時候使用 Managed Table 跟 External Table?

  • Managed Table
    • 適用於臨時創建的中間表
  • External Table
    • 適用於數據多部門共享

5、hive 有哪些複合數據類型?

1、MAP

    a.Map 複合數據類型提供了 key-value 對存儲,你可以通過 key 獲取 value。
    b.zhangsan Math:90,Chinese:92,English:78
        i.create table score_map(name string, score map<string, int>) map keys terminated by ':';
        ii.select name, score['English'], size(score) from score_map;

2、STRUCT

    a.Struct 是不同數據類型元素的集合。
    b.zhangsan Math,90
        i.create table course_struct(name string, course struct<course: string, score: int>) collection items terminated by ',';
        ii.select name, course.score, course.course from course_struct;

3、ARRAY

    a.Array 是同類型元素的集合.
    b.zhangsan beijing,shanghai,hangzhou
        i.create table person_array(name string, work_locations array<string>) collection items terminated by ',';
        ii.select name, work_locations[0], size(work_locations) from person_array;

4、UNIONTYPE

    a.它代表一個可以具有屬於你所選擇的任何數據類型的值的列。
    b.官方支持不完整,在 join 查詢中,group by 或者 where 字句會失敗,目前可以不用這個集合。

6、hive 分區有什麼好處?

  • 最大的好處就是可以更快的執行查詢。
  • 在分區的幫助下,將使用分區列的名稱創建一個子目錄,並且當使用 WHERE 子句執行查詢時,將只掃描特定的子目錄,而不是掃描整個表。這時可以更快地執行查詢。

7、hive 分區跟分桶的區別

  • 分區: 是以字段的形式在表結構中存在,通過 describe table 命令可以查看到字段存在,但是該字段不存放實際的數據內容,僅僅是分區的表示(僞列)。
  • 分桶:對於表(table)或者分區,Hive 可以進一步組織成桶,也就是說桶是更爲細粒度的數據範圍劃分。Hive 也是針對某一列進行桶的組織。Hive 採用對列值哈希,然後除以桶的個數求餘的方式決定該條記錄存放在哪個桶當中。實際使用比較少。

8、hive 如何動態分區

  • 與分區有關的有兩種類型的分區:靜態和動態。在靜態分區中,您將在加載數據時(顯式)指定分區列。
  • 而在動態分區中,您將數據推送到 Hive,然後 Hive 決定哪個值應進入哪個分區。要啓用動態分區,請設置下面的屬性:hive.exec.dynamic.parition.mode=nonstrict;
insert overwrite table emp_details_partitioned partition(location)
select * from emp_details;

9、map join 優化手段

Hive 可以進行多表 JoinJoin 操作尤其是 Join 大表的時候代價是非常大的。

表 Join 的順序(大表放在後面)
    當 Hive 執行 Join 時,需要選擇哪個表被流式傳輸(stream),哪個表被緩存(cache)。 Hive 將 JOIN 語句中的最後一個表用於流式傳輸,因此我們需要確保這個流表在兩者之間是最大的。
    如果要在不同的 keyjoin 更多的表,那麼對於每個 join 集,只需在 ON 條件右側指定較大的表。 

Sort-Merge-Bucket(SMB) Map Join
    它是另一種 Hive join 優化技術,使用這個技術的前提是所有的表都必須是桶分區(bucket)和排序了的(sort)。
    set hive.enforce.sortmergebucketmapjoin=false;  -- 當用戶執行 bucket map join 的時候,發現不能執行時,禁止查詢。
    set hive.auto.convert.sortmerge.join=true;  -- 如果 join 的表通過 sort merge join 的條件,join 是否會自動轉換爲 sort merge join。
    set hive.optimize.bucketmapjoin=true;  -- bucket map join 優化
    set hive.optimize.bucketmapjoin.sortedmerge=true;  -- bucket map join 優化
    set hive.auto.convert.join=false;  -- 禁止自動 map side join 發生

10、如何創建 bucket 表?

  • 默認情況下,在 Hive 中禁用分桶功能,可以通過設置下面的屬性強制啓用分桶功能:hive.enforce.bucketing=true;

11、hive 有哪些 file formats

Text File format : 默認格式,數據不做壓縮,磁盤開銷大,數據解析開銷大。

Sequence File format :
    SequenceFile 是 Hadoop API 提供的一種二進制文件支持,其具有使用方便、可分割、可壓縮的特點。
    SequenceFile 支持三種壓縮選擇:NONE, RECORD, BLOCK。 Record 壓縮率低,一般建議使用 BLOCK 壓縮。

RC file format : RCFILE 是一種行列存儲相結合的存儲方式。首先,其將數據按行分塊,保證同一個 record 在一個塊上,避免讀一個記錄需要讀取多個 block。其次,塊數據列式存儲,有利於數據壓縮和快速的列存取。RCFile 目前沒有性能優勢,只有存儲上能省 10% 的空間。

Parquet : 列式數據存儲。
AVRO : avro Schema 數據序列化。
ORC : 對RCFile做了一些優化,支持各種複雜的數據類型。

12、hive 最優的 file formats 是什麼?

ORC file formats: 
    1、ORC 將行的集合存儲在一個文件中,並且集合內的行數據將以列式存儲。採用列式格式,壓縮非常容易,從而降低了大量的存儲成本。
    2、當查詢時,會查詢特定列而不是查詢整行,因爲記錄是以列式存儲的。
    3、ORC 會基於列創建索引,當查詢的時候會很快。

13、hive 傳參

使用 env 獲取當前 shell 環境的環境變量
eg: export datatime=2017-11-10select * from tabliname where datatime = ${env:datatime};

使用 --hivevar 方式傳入
hive --hivevar datatime ='datatime' --hivevar limit=10 -f filename.sql
select * from tablename where datatime = ${hivevar:datatime} limit ${hivevar:limit}

14、order by 和 sort by 的區別

使用 order by 會引發全局排序,有可能會導致任務失敗。
使用 distribute by + sort by 替代方案,進行優化。

15、hive 跟 hbase 的區別

hive 支持 sql 查詢,hbase 不支持。
hive 不支持 record 級(一行記錄)的更新,刪除操作。
hive 定義爲數據倉庫,hbase 定義爲 nosql 數據庫。

二、Hive 數據分析面試

場景舉例:北京市學生成績分析
成績的數據格式:時間,學校,年紀,姓名,科目,成績
樣例數據如下:

2013,北大,1,裘容絮,語文,97
2013,北大,1,慶眠拔,語文,52
2013,北大,1,烏灑籌,語文,85
2012,清華,0,欽堯,英語,61
2015,北理工,3,冼殿,物理,81
2016,北科,4,況飄索,化學,92
2014,北航,2,孔須,數學,70
2012,清華,0,王脊,英語,59
2014,北航,2,方部盾,數學,49
2014,北航,2,東門雹,數學,77

問題:

1、分組 TopN,選出今年每個學校、每個年級、分數前三的科目

hive -e "
set mapreduce.job.queuename=low;
select t.*
from
(
select
       school,
       class,
       subjects,
       score,
       row_number() over (partition by school, class, subjects order by score desc) rank_code
from spark_test_wx
where partition_id = "2017"
) t
where t.rank_code <= 3;
"

結果截圖如下:

詳解如下:
  row_number函數:row_number() 按指定的列進行分組生成行序列,從 1 開始,如果兩行記錄的分組列相同,則行序列 +1。
  over 函數:是一個窗口函數。
  over (order by score) 按照 score 排序進行累計,order by 是個默認的開窗函數。
  over (partition by class) 按照班級分區。
  over (partition by class order by score) 按照班級分區,並按着分數排序。
  over (order by score range between 2 preceding and 2 following) 窗口範圍爲當前行的數據幅度減2加2後的範圍內的數據求和。

2、今年,北航,每個班級,每科的分數,及分數上下浮動 2 分的總和

select school, class, subjects, score,
sum(score) over (order by score range between 2 preceding and 2 following) sscore
from spark_test_wx
where partition_id = "2017" and school="北航";

結果截圖如下:

over (order by score rows between 2 preceding and 2 following):窗口範圍爲當前行前後各移動2行。

提問,上述 sql 有沒有可優化的點?

row_number() over (distribute by school, class, subjects sort by score desc) rank_code

3、where 與 having:今年,清華 1 年級,總成績大於 200 分的學生以及學生數

hive -e "
set mapreduce.job.queuename=low;
select school,class,name,sum(score) as total_score,
count(1) over (partition by school, class) nct
from spark_test_wx
where partition_id = "2017" and school="清華" and class = 1
group by school, class, name
having total_score > 200;
"

結果截圖如下:

having 是分組(group by)後的篩選條件,分組後的數據組內再篩選,也就是說 HAVING 子句可以讓我們篩選成組後的各組數據。
where 則是在分組,聚合前先篩選記錄。也就是說作用在 GROUP BY 子句和 HAVING 子句前。

4、情景分析題
今年加入進來了 10 個學校,學校數據差異很大計算每個學校的平均分。
該題主要是考察數據傾斜的處理方式。
group by 方式很容易產生數據傾斜,需要注意一下幾點:

Map 端部分聚合
hive.map.aggr=true(用於設定是否在 map 端進行聚合,默認值爲真,相當於 combine) 
hive.groupby.mapaggr.checkinterval=100000(用於設定 map 端進行聚合操作的條數)

有數據傾斜時進行負載均衡
設定 hive.groupby.skewindata,當選項設定爲 true 是,生成的查詢計劃有兩個 MapReduce 任務。

(先打散數據)
第一個 MapReduce 中,map 的輸出結果集合會隨機分佈到 reduce 中, 每個 reduce 做部分聚合操作,並輸出結果。這樣處理的結果是,相同的 group by key 有可能分發到不同的 reduce 中,從而達到負載均衡的目的;

第二個 MapReduce 任務再根據預處理的數據結果按照 group by key 分佈到 reduce 中(這個過程可以保證相同的 group by key 分佈到同一個 reduce 中),最後完成最終的聚合操作。

5、情景分析題
假設我創建了一張表,其中包含了 2016 年客戶完成的所有交易的詳細信息:

CREATE TABLE transaction_details (cust_id INT, amount FLOAT, month STRING, country STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY,;

現在我插入了 100 萬條數據,我想知道每個月的總收入。

問:如何高效的統計出結果,寫出步驟即可。

1.首先分析這個需求,其實並不難,但是由於題目說了,要高效.而且數據量也不小,直接寫sql查詢估計肯定會掛.
2.分析:
    a.我們可以通過根據每個月對錶進行分區來解決查詢慢的問題。 因此,對於每個月我們將只掃描分區的數據,而不是整個數據集。
    b.但是我們不能直接對現有的非分區表進行分區。所以我們會採取以下步驟來解決這個問題:
    c.創建一個分區表,partitioned_transaction:
        i.create table partitioned_transaction (cust_id int, amount float, country string) partitioned by (month string) row format delimited fields terminated by,;
    d.在 Hive 中啓用動態分區:
        i.SET hive.exec.dynamic.partition=true;
        ii.SET hive.exec.dynamic.partition.mode=nonstrict;
    e.將數據從非分區表導入到新創建的分區表中:
        i.insert overwrite table partitioned_transaction partition (month) select cust_id, amount, country, month from transaction_details;
    f.使用新建的分區表實現需求。

三、Flume + Kafka 面試

1、flume 如何保證數據的可靠性?

  • Flume 提供三種可靠性:JDBC、FILE、MEMORY
  • Flume 使用事務的辦法來保證 event 的可靠傳遞。Source 和 Sink 分別被封裝在事務中,這些事務由保存 event 的存儲提供或者由 Channel 提供。這就保證了 event 在數據流的點對點傳輸中是可靠的。

2、kafka 數據丟失問題,及如何保證?

1、kafka 數據丟失問題

a、acks=1    的時候(只保證寫入 leader 成功),如果剛好 leader 掛了,則數據會丟失。
b、acks=0    的時候,使用異步模式的時候,該模式下 kafka 無法保證消息,有可能會丟。

2、brocker 如何保證不丟失

a、acks=all      所有副本都寫入成功並確認。
b、retries=一個合理值        kafka 發送數據失敗後的重試值。(如果總是失敗,則可能是網絡原因)
c、min.insync.replicas=2     消息至少要被寫入到這麼多副本纔算成功。
d、unclean.leader.election.enable=false      關閉 unclean leader 選舉,即不允許非 ISR 中的副本被選舉爲 leader,以避免數據丟失。

3、consumer 如何保證不丟失?

a、如果在消息處理完成前就提交了 offset,那麼就有可能造成數據的丟失。
b、enable.auto.commit=false     關閉自動提交 offset。
c、處理完數據之後手動提交。

3、kafka 工作流程原理

大致原理即可。有幾個點稍微詳細即可。

4、kafka 保證消息順序

1、全局順序
  a、全局使用一個生產者,一個分區,一個消費者。
2、局部順序
  a、每個分區是有序的,根據業務場景制定不同的 key 進入不同的分區。

5、zero copy 原理及如何使用?

  • 1、zero copy 在內核層直接將文件內容傳送給網絡 socket,避免應用層數據拷貝,減小 IO 開銷。
  • 2、java.nio.channel.FileChannel 的 transferTo() 方法實現 zero copy。

6、spark Join 常見分類以及基本實現機制

1、shuffle hash join、broadcast hash join 以及 sort merge join。

2、shuffle hash join

小表 join 大表,依次讀取小表的數據,對於每一行數據根據 join key 進行 hash,hash 到對應的 Bucket(桶),生成 hash table 中的一條記錄。
數據緩存在內存中,如果內存放不下需要 dump 到外存。
再依次掃描大表的數據,使用相同的 hash 函數映射 Hash Table 中的記錄,映射成功之後再檢查 join 條件,如果匹配成功就可以將兩者 join 在一起。

3、broadcast hash join

如果小表數據量增大,內存不能放下的時候,分別將兩個表按照 join key 進行分區,將相同 join key 的記錄重分佈到同一節點,兩張表的數據會被重分佈到集羣中所有節點。這個過程稱爲 shuffle(網絡混啓)。
每個分區節點上的數據單獨執行單機 hash join 算法。

4、sort merge join

兩張大表 join 採用了 sort merge join 算法:
    shuffle 階段:將兩張大表根據 join key 進行重新分區,兩張表數據會分佈到整個集羣,以便分佈式並行處理。
    sort 階段:對單個分區節點的兩表數據,分別進行排序。
    merge 階段:對排好序的兩張分區表數據執行 join 操作。join 操作很簡單,分別遍歷兩個有序序列,碰到相同 join key 就 merge 輸出,否則取更小一邊。

128G 內存、多磁盤、萬兆網卡、吞吐(幾千到一萬)

我的GitHub地址:https://github.com/heizemingjun
我的博客園地址:https://www.cnblogs.com/chenmingjun
我的CSDN地址:https://blog.csdn.net/u012990179
我的螞蟻筆記博客地址:https://blog.leanote.com/chenmingjun
Copyright ©2018~2019 黑澤君
【轉載文章務必保留出處和署名,謝謝!】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章