Hive動態分割槽詳解

柯廣發表於2020-12-23

動態分割槽調整

  • 動態分割槽屬性:設定為true表示開啟動態分割槽功能(預設為false)hive.exec.dynamic.partition=true;
  • 動態分割槽屬性:設定為nonstrict,表示允許所有分割槽都是動態的(預設為strict)設定為strict,表示必須保證至少有一個分割槽是靜態的hive.exec.dynamic.partition.mode=strict;
  • 動態分割槽屬性:每個mapper或reducer可以建立的最大動態分割槽個數hive.exec.max.dynamic.partitions.pernode=100;
  • 動態分割槽屬性:一個動態分割槽建立語句可以建立的最大動態分割槽個數hive.exec.max.dynamic.partitions=1000;
  • 動態分割槽屬性:全域性可以建立的最大檔案個數hive.exec.max.created.files=100000;
  • 控制DataNode一次可以開啟的檔案個數 這個引數必須設定在DataNode的$HADOOP_HOME/conf/hdfs-site.xml檔案中
<property>
    <name>dfs.datanode.max.xcievers</name>
    <value>8192</value>
</property>

注意

在Hive中,動態分割槽會造成在插入資料過程中,生成過多零碎的小檔案

動態分割槽插入

如果需要建立非常多的分割槽,使用者就需要寫非常多的條件查詢sql把資料插入對應分割槽。好在Hive提供了動態分割槽功能,可以根據分割槽欄位的取值自動建立分割槽。前面列出的開啟動態分割槽hive.exec.dynamic.partition,並且hive.exec.dynamic.partition.mode需要為非嚴格模式,通常如果分割槽很多的話,hive.exec.max.dynamic.partitions.pernode也需要設定為一個較大的數,否則會有報錯提醒。

現在有sql

insert overwrite table employees partitions (country, state)
select ...,se.cnty, se.st
from staged_employees se;

可以看出,Hive根據select語句中最後兩列來確定分割槽欄位countrystate的值,這裡刻意使用了不同的命名,就是為了強調源表欄位和輸出分割槽值之間的關係是根據位置而不是根據命名來匹配的。

動靜分割槽結合

也可以混合使用動態和靜態分割槽。上面那個例子,我們可以指定國家這個分割槽值五為靜態值US,而分割槽欄位state是動態值:

insert overwrite table employees partitions (country = 'US', state)
select ...,se.cnty, se.st
from staged_employees se
where se.cnty = 'US';

注意:靜態分割槽需要出現在動態分割槽欄位之前。

動態分割槽功能預設情況下是沒有開啟的,預設是以嚴格模式執行,這種模式下要求至少有一列分割槽欄位是靜態的。這樣做的好處是可以防止因設計或其它錯誤查詢導致產生大量的分割槽,比如sql boy不小心使用了時間戳作為分割槽欄位,那將是災難。在日常匯入一天的資料,通常是指定日期為靜態分割槽,小時為動態分割槽,進行混合模式匯入。

例子

建表

create table if not exists test.test
(
id string,
name string
)
partitioned by (dt string,hour string)
row format delimited fields terminated by '\t';

create table if not exists test.test2
(
id string,
name string
)
partitioned by (dt string,hour string)
row format delimited fields terminated by '\t'
stored as orc;

匯入資料到test.test

load data local inpath '/home/hadoop/data/test.txt' into table test.test partition(dt = '2019-09-10', hour = '02');

test.txt
001	keguang
002	kg
003	kk
004	ikeguang

利用動態分割槽插入

insert overwrite table test.test2 partition(dt, hour) select `(dt|hour)?+.+`,dt,hour from test.test;

這裡,(dt|hour)?+.+表示查詢出test表除了dthour這兩個欄位的其它所有欄位。

相關文章