1、Hive 基本面試一、什麼是 metastore二、metastore 安裝方式有什麼區別三、什麼是 Managed Table 跟 External Table?四、何時使用 Managed Table 跟 External Table?五、hive 有哪些複合數據類型?六、hive 分區有什麼好處?七、hive 分區跟分桶的區別八、hive 如何動態分區九、map join 優化手段十、如何建立 bucket 表?十一、hive 有哪些 file formats十二、hive 最優的 file formats 是什麼?1三、hive 傳參1四、order by 和 sort by 的區別1五、hive 跟 hbase 的區別2、Hive 數據分析面試一、分組 TopN,選出今年每一個學校、每一個年級、分數前三的科目二、今年,北航,每一個班級,每科的分數,及分數上下浮動 2 分的總和三、where 與 having:今年,清華 1 年級,總成績大於 200 分的學生以及學生數3、Flume + Kafka 面試一、flume 如何保證數據的可靠性?二、kafka 數據丟失問題,及如何保證?三、kafka 工做流程原理四、kafka 保證消息順序五、zero copy 原理及如何使用?六、spark Join 常見分類以及基本實現機制java
metadata 即元數據。包含 database、tabel、column names、partitions 信息、bucketing 信息等的元數據信息。
元數據默認是存儲在 Derby 中,建議存儲在關係型數據庫中。mysql
內嵌模式
內嵌模式使用的是內嵌的 Derby 數據庫來存儲元數據,也不須要額外起 Metastore 服務。這個是默認的,配置簡單,可是一次只能一個客戶端鏈接,適用於用來實驗,不適用於生產環境。web
本地元存儲
本地安裝 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。算法
/user/username/hive/warehouse
。describe formatted table_name;
命令來查看錶的信息。drop table table_name;
刪除表時,數據文件也會一併刪除。一、MAPsql
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;
二、STRUCTshell
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;
三、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;
四、UNIONTYPE緩存
a.它表明一個能夠具備屬於你所選擇的任何數據類型的值的列。
b.官方支持不完整,在 join 查詢中,group by 或者 where 字句會失敗,目前能夠不用這個集合。
是以字段的形式在表結構中存在
,經過 describe table 命令能夠查看到字段存在,可是該字段不存放實際的數據內容,僅僅是分區的表示(僞列)。Hive 採用對列值哈希
,而後除以桶的個數求餘的方式決定該條記錄存放在哪一個桶當中。實際使用比較少。insert overwrite table emp_details_partitioned partition(location)
select * from emp_details;
Hive 能夠進行多表 Join。Join 操做尤爲是 Join 大表的時候代價是很是大的。
表 Join 的順序(大表放在後面)
當 Hive 執行 Join 時,須要選擇哪一個表被流式傳輸(stream),哪一個表被緩存(cache)。 Hive 將 JOIN 語句中的最後一個表用於流式傳輸,所以咱們須要確保這個流表在二者之間是最大的。
若是要在不一樣的 key 上 join 更多的表,那麼對於每一個 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 發生
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作了一些優化,支持各類複雜的數據類型。
ORC file formats:
一、ORC 將行的集合存儲在一個文件中,而且集合內的行數據將以列式存儲。採用列式格式,壓縮很是容易,從而下降了大量的存儲成本。
二、當查詢時,會查詢特定列而不是查詢整行,由於記錄是以列式存儲的。
三、ORC 會基於列建立索引,當查詢的時候會很快。
使用 env 獲取當前 shell 環境的環境變量
eg: export datatime=’2017-11-10’
select * 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}
使用 order by 會引起全局排序,有可能會致使任務失敗。
使用 distribute by + sort by 替代方案,進行優化。服務器
hive 支持 sql 查詢,hbase 不支持。
hive 不支持 record 級(一行記錄)的更新,刪除操做。
hive 定義爲數據倉庫,hbase 定義爲 nosql 數據庫。
場景舉例:北京市學生成績分析
成績的數據格式:時間,學校,年紀,姓名,科目,成績
樣例數據以下:
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
問題:
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;
"
結果截圖以下:
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
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 子句前。
四、情景分析題
今年加入進來了 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 中),最後完成最終的聚合操做。
五、情景分析題
假設我建立了一張表,其中包含了 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.使用新建的分區表實現需求。
一、kafka 數據丟失問題
a、acks=1 的時候(只保證寫入 leader 成功),若是恰好 leader 掛了,則數據會丟失。
b、acks=0 的時候,使用異步模式的時候,該模式下 kafka 沒法保證消息,有可能會丟。
二、brocker 如何保證不丟失
a、acks=all 全部副本都寫入成功並確認。
b、retries=一個合理值 kafka 發送數據失敗後的重試值。(若是老是失敗,則多是網絡緣由)
c、min.insync.replicas=2 消息至少要被寫入到這麼多副本纔算成功。
d、unclean.leader.election.enable=false 關閉 unclean leader 選舉,即不容許非 ISR 中的副本被選舉爲 leader,以免數據丟失。
三、consumer 如何保證不丟失?
a、若是在消息處理完成前就提交了 offset,那麼就有可能形成數據的丟失。
b、enable.auto.commit=false 關閉自動提交 offset。
c、處理完數據以後手動提交。
大體原理便可。有幾個點稍微詳細便可。
一、全局順序
a、全局使用一個生產者,一個分區,一個消費者。
二、局部順序
a、每一個分區是有序的,根據業務場景制定不一樣的 key 進入不一樣的分區。
一、shuffle hash join、broadcast hash join 以及 sort merge join。
二、shuffle hash join
小表 join 大表,依次讀取小表的數據,對於每一行數據根據 join key 進行 hash,hash 到對應的 Bucket(桶),生成 hash table 中的一條記錄。
數據緩存在內存中,若是內存放不下須要 dump 到外存。
再依次掃描大表的數據,使用相同的 hash 函數映射 Hash Table 中的記錄,映射成功以後再檢查 join 條件,若是匹配成功就能夠將二者 join 在一塊兒。
三、broadcast hash join
若是小表數據量增大,內存不能放下的時候,分別將兩個表按照 join key 進行分區,將相同 join key 的記錄重分佈到同一節點,兩張表的數據會被重分佈到集羣中全部節點。這個過程稱爲 shuffle(網絡混啓)。
每一個分區節點上的數據單獨執行單機 hash join 算法。
四、sort merge join
兩張大表 join 採用了 sort merge join 算法:
shuffle 階段:將兩張大表根據 join key 進行從新分區,兩張表數據會分佈到整個集羣,以便分佈式並行處理。
sort 階段:對單個分區節點的兩表數據,分別進行排序。
merge 階段:對排好序的兩張分區表數據執行 join 操做。join 操做很簡單,分別遍歷兩個有序序列,碰到相同 join key 就 merge 輸出,不然取更小一邊。
128G 內存、多磁盤、萬兆網卡、吞吐(幾千到一萬)