Hive的分区(partition)-动态分区
Hive的分區
聲明:本文為博主參考網上資料整理的文章,未經博主允許不得轉載,如有問題,歡迎指正。
一、概述
分區是hive存放數據的一種方式。將列值作為目錄來存放數據,就是一個分區。這樣查詢時使用分區列進行過濾,只需根據列值直接掃描對應目錄下的數據,不掃描其他不關心的分區,快速定位,提高查詢效率。hive中支持兩種類型的分區:
靜態分區SP(static partition)
動態分區DP(dynamic partition)
靜態分區與動態分區的主要區別在于靜態分區是手動指定,而動態分區是通過數據來進行判斷。詳細來說,靜態分區的列是在編譯時期,通過用戶傳遞來決定的;動態分區只有在SQL執行時才能決定。
二、動態分區說明
關系型數據庫(如Oracle)中,對分區表Insert數據時候,數據庫自動會根據分區字段的值,將數據插入到相應的分區中,Hive中也提供了類似的機制,即動態分區(Dynamic Partition)。
按照常規的方法向分區表中插入數據,如果源數據量很大,那么針對一個分區就要寫一個insert,非常麻煩,而且你必須先要知道源數據中都有什么樣的數據才能創建分區。例如:
hive> insert overwrite table partition_test partition(stat_date='20110728',province='henan') select member_id,name from partition_test_input where stat_date='20110728' and province='henan';使用動態分區可以很好的解決上述問題。動態分區可以根據查詢得到的數據自動匹配到相應的分區中去。只不過,使用Hive的動態分區,需要進行相應的配置。
三、動態分區的相關配置
●set hive.exec.dynamic.partition=true;–是否允許動態分區
? ?默認值:false
? ?是否開啟動態分區功能,默認false關閉。
? ?使用動態分區時候,該參數必須設置成true。
●set hive.exec.dynamic.partition.mode=nonstrict; --分區模式設置
? ?默認值:strict
? ?動態分區的模式,默認strict,表示必須指定至少一個分區為靜態分區。
? ?nonstrict模式:表示允許所有的分區字段都可以使用動態分區。
●set hive.exec.max.dynamic.partitions.pernode=1000;–單個節點上的mapper/reducer允許創建的最大分區
? ?默認值:100
? ?在每個執行MR的節點上,最大可以創建多少個動態分區。該參數需要根據實際的數據來設定。
? ?比如:源數據中包含了一年的數據,即day字段有365個值,那么該參數就需要設置成大于365,如果使用默認值100,則會報錯。
●set hive.exec.max.dynamic.partitions=1500;–允許動態分區的最大數量
? ?默認值:1000
? ?在所有執行MR的節點上,最大一共可以創建多少個動態分區。
? ?同上參數解釋。
●hive.exec.max.created.files=100000;–一個mapreduce作業能創建的HDFS文件最大數
? ?默認值:100000
? ?整個MR Job中,最大可以創建多少個HDFS文件。
? ?一般默認值足夠了,除非你的數據量非常大,需要創建的文件數大于100000,可根據實際情況加以調整。
此處補充知識點:使用動態分區可能遇到分區文件數超10萬的情況,解決辦法參考distribute by控制分區文件數
●hive.error.on.empty.partition=false;–在動態分區插入產生空結果時是否拋出異常
? ?默認值:false
? ?當有空分區生成時,是否拋出異常。一般不需要設置。
四、動態分區的操作
創建分區表
create table if not exists partition_test (member_id string,name string )partitioned by(stat_date string,province string) ;設置動態分區參數
set hive.exec.dynamic.partition=true; set hive.exec.dynamic.partition.mode=nonstrict; set hive.exec.max.dynamic.partitions.pernode=1000; set hive.exec.max.dynamic.partitions=1500;插入數據
動態分區的使用方法很簡單,假設我想向stat_date='20110728’這個分區下面插入數據,至于province插入到哪個子分區下面讓數據庫自己來判斷。那可以這樣寫:
stat_date叫做靜態分區列,province叫做動態分區列。這樣stat_date='20110728’的所有數據,會根據province的不同分別插入到/user/hive/warehouse/partition_test/stat_date=20110728/下面的不同的子文件夾下,如果源數據對應的province子分區不存在,則會自動創建,非常方便,而且避免了人工控制插入數據與分區的映射關系存在的潛在風險。
注:select子句中需要把動態分區列按照分區的順序寫出來,靜態分區列不用寫出來。
五、分區注意細節
1、盡量不要用動態分區,因為動態分區的時候,將會為每一個分區分配reducer數量,當分區數量多的時候,reducer數量將會增加,對服務器是一種災難。
2、動態分區和靜態分區的區別,靜態分區不管有沒有數據都將會創建該分區,動態分區是有結果集將創建,否則不創建。
3、hive動態分區的嚴格模式和hive提供的hive.mapred.mode的嚴格模式。
? ?hive提供我們一個嚴格模式:為了阻止用戶不小心提交惡意hql
? ?hive.mapred.mode=nostrict : strict
? ?如果該模式值為strict,將會阻止以下三種查詢:
? ?? ?(1)對分區表查詢,where中過濾字段不是分區字段。
? ?? ?(2)笛卡爾積join查詢,join查詢語句,不帶on條件或者where條件。
? ?? ?(3)對order by查詢,有order by的查詢不帶limit語句。
4、動態分區不允許主分區采用動態列而副分區采用靜態列,這樣將導致所有的主分區都要創建副分區靜態列所定義的分區。
5、動態分區可以允許所有的分區列都是動態分區列,但是要首先設置一個參數:hive.exec.dynamic.partition.mode。
6、注意!!!
hive用了動態分區,若select語句無數據,則insert overwrite并不會覆蓋。因為動態分區由select決定,select語句無數據,分區也無法確定,故無法實現動態覆蓋。此時想要修正表數據,需要手動刪除該分區。
[參考資料1]:動態分區說明
[參考資料2]:大數據開發學習之Hive的動態分區
總結
以上是生活随笔為你收集整理的Hive的分区(partition)-动态分区的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: web前端自动化测试(基于QT4W框架)
- 下一篇: 仿真测试 | HIL测试简单介绍