面試題:
- hive 內部表和外部表的區別?
- hive 是如何實現分區的?
- Hive 有哪些方式保存元數據,各有哪些優缺點?
- hive中order by、distribute by、sort by和cluster by的區別和聯系
- hive 中的壓縮格式 RCFile、 TextFile、 SequenceFile 各有什么區別?
- hive 如何優化?
hive 內部表和外部表的區別?
- 未被external修飾的是內部表(managed table),被external修飾的為外部表(external table);
- 內部表數據由Hive自身管理,外部表數據由HDFS管理;
- 內部表數據存儲的位置是hive.metastore.warehouse.dir(默認:/user/hive/warehouse),外部表數據的存儲位置由自己制定(如果沒有LOCATION,Hive將在HDFS上的/user/hive/warehouse文件夾下以外部表的表名創建一個文件夾,並將屬於這個表的數據存放在這里);
- 刪除內部表會直接刪除元數據(metadata)及存儲數據;刪除外部表僅僅會刪除元數據,HDFS上的文件並不會被刪除;
- 對內部表的修改會將修改直接同步給元數據,而對外部表的表結構和分區進行修改,則需要修復(MSCK REPAIR TABLE table_name;)
- 修改外部表想要生效,需要先把外部表轉內部表,然后修改,再轉外部表。
hive 是如何實現分區的?
建表語句:
create table tablename (id) partitioned by (dt string)
增加分區:
alter table tablenname add partition (dt = ‘2016-03-06’)
刪除分區:
alter table tablename drop partition (dt = ‘2016-03-06’)
Hive 有哪些方式保存元數據,各有哪些優缺點?
存儲於 derby數據庫,此方法只能開啟一個hive客戶端,不推薦使用
存儲於mysql數據庫中,可以多客戶端連接,推薦使用
hive中order by、distribute by、sort by和cluster by的區別和聯系
order by
order by 會對數據進行全局排序,和oracle和mysql等數據庫中的order by 效果一樣,它只在一個reduce中進行所以數據量特別大的時候效率非常低。
而且當設置 :set hive.mapred.mode=strict的時候不指定limit,執行select會報錯,如下:
LIMIT must also be specified。
sort by
sort by 是單獨在各自的reduce中進行排序,所以並不能保證全局有序,一般和distribute by 一起執行,而且distribute by 要寫在sort by前面。
如果mapred.reduce.tasks=1和order by效果一樣,如果大於1會分成幾個文件輸出每個文件會按照指定的字段排序,而不保證全局有序。
sort by 不受 hive.mapred.mode 是否為strict ,nostrict 的影響。
distribute by
DISTRIBUTE BY 控制map 中的輸出在 reducer 中是如何進行划分的。使用DISTRIBUTE BY 可以保證相同KEY的記錄被划分到一個Reduce 中。
cluster by
distribute by 和 sort by 合用就相當於cluster by,但是cluster by 不能指定排序為asc或 desc 的規則,只能是升序排列。
hive 中的壓縮格式 RCFile、 TextFile、 SequenceFile 各有什么區別?
TextFile:默認格式,數據不做壓縮,磁盤開銷大,數據解析開銷大
SequenceFile:Hadoop API提供的一種二進制文件支持,使用方便,可分割,可壓縮,支持三種壓縮,NONE,RECORD,BLOCK。
RCFILE:是一種行列存儲相結合的方式。首先,將數據按行分塊,保證同一個 record 在同一個塊上,避免讀一個記錄讀取多個block。其次,塊數據列式存儲,有利於數據壓縮和快速的列存取。數據加載的時候性能消耗大,但具有較好的壓縮比和查詢響應。
hive 如何優化?
join 優化,盡量將小表放在 join 的左邊,如果一個表很小可以采用 mapjoin。
排序優化,order by 一個 reduce 效率低,distirbute by +sort by 也可以實現全局排序。
使用分區,查詢時可減少數據的檢索,從而節省時間。
# 海量數據分布在100台電腦中,想個辦法高效統計出這批數據的TOP10
方案1:
a) 在每台電腦上求出TOP10,可以采用包含10個元素的堆完成(TOP10小,用最大堆,TOP10大,用最小堆)。
b) 比如求TOP10大,我們首先取前10個元素調整成最小堆,如果發現,然后掃描后面的數據,並與堆頂元素比較,如果比堆頂元素大,那么用該元素替換堆頂,然后再調整為最小堆。
c) 最后堆中的元素就是TOP10大
方案2
a) 求出每台電腦上的TOP10后,然后把這100台電腦上的TOP10組合起來,共1000個數據
b) 再利用上面類似的方法求出TOP10就可以了。
row_number()、rank()、dense_rank() 區別
ROW_NUMBER()函數作用就是將select查詢到的數據進行排序,每一條數據加一個序號,他不能用做於學生成績的排名,一般多用於分頁查詢。
RANK()函數,顧名思義排名函數,可以對某一個字段進行排名,這里為什么和ROW_NUMBER()不一樣那,ROW_NUMBER()是排序,當存在相同成績的學生時,ROW_NUMBER()會依次進行排序,他們序號不相同,而Rank()則不一樣出現相同的,他們的排名是一樣的。
DENSE_RANK()函數也是排名函數,和RANK()功能相似,也是對字段進行排名。
hive 開窗函數有哪些?
開窗函數一般用於數據分析,計算基於組的某種聚合值。
跟聚合函數的區別在於:對於每個組返回多行,而聚合函數對於每個組只返回一行。
開窗函數指定了分析函數工作的數據窗口大小,這個數據窗口大小可能會隨着行的變化而變化!
基礎結構:分析函數(如:sum(),max(),row_number()...) + 窗口子句(over函數)
例如:sum() over(partition by user_id order by order_time desc)
over函數寫法: over(partition by cookieid order by createtime) 先根據cookieid字段分區,相同的cookieid分為一區,每個分區內根據createtime字段排序(默認升序)
注:不加 partition by 的話則把整個數據集當作一個分區,不加 order by的話會對某些函數統計結果產生影響,如sum()
分析函數有:avg(),min(),max(),sum()
排序函數:row_number(), rank(), dense_rank()