Hive動態(tài)分區(qū)詳解

Hive系列文章

  1. Hive表的基本操作
  2. Hive中的集合數(shù)據(jù)類型
  3. Hive動態(tài)分區(qū)詳解
  4. hive中orc格式表的數(shù)據(jù)導入
  5. Java通過jdbc連接hive
  6. 通過HiveServer2訪問Hive
  7. SpringBoot連接Hive實現(xiàn)自助取數(shù)
  8. hive關(guān)聯(lián)hbase表
  9. Hive udf 使用方法
  10. Hive基于UDF進行文本分詞
  11. Hive窗口函數(shù)row number的用法
  12. 數(shù)據(jù)倉庫之拉鏈表

動態(tài)分區(qū)調(diào)整

  • 動態(tài)分區(qū)屬性:設置為true表示開啟動態(tài)分區(qū)功能(默認為false)hive.exec.dynamic.partition=true;
  • 動態(tài)分區(qū)屬性:設置為nonstrict,表示允許所有分區(qū)都是動態(tài)的(默認為strict)設置為strict,表示必須保證至少有一個分區(qū)是靜態(tài)的hive.exec.dynamic.partition.mode=strict;
  • 動態(tài)分區(qū)屬性:每個mapper或reducer可以創(chuàng)建的最大動態(tài)分區(qū)個數(shù)hive.exec.max.dynamic.partitions.pernode=100;
  • 動態(tài)分區(qū)屬性:一個動態(tài)分區(qū)創(chuàng)建語句可以創(chuàng)建的最大動態(tài)分區(qū)個數(shù)hive.exec.max.dynamic.partitions=1000;
  • 動態(tài)分區(qū)屬性:全局可以創(chuàng)建的最大文件個數(shù)hive.exec.max.created.files=100000;
  • 控制DataNode一次可以打開的文件個數(shù) 這個參數(shù)必須設置在DataNode的$HADOOP_HOME/conf/hdfs-site.xml文件中
    <property>
    <name>dfs.datanode.max.xcievers</name>
    <value>8192</value>
    </property>
    XML

注意

在Hive中,動態(tài)分區(qū)會造成在插入數(shù)據(jù)過程中,生成過多零碎的小文件

動態(tài)分區(qū)插入

如果需要創(chuàng)建非常多的分區(qū),用戶就需要寫非常多的條件查詢sql把數(shù)據(jù)插入對應分區(qū)。好在Hive提供了動態(tài)分區(qū)功能,可以根據(jù)分區(qū)字段的取值自動創(chuàng)建分區(qū)。前面列出的開啟動態(tài)分區(qū)hive.exec.dynamic.partition,并且hive.exec.dynamic.partition.mode需要為非嚴格模式,通常如果分區(qū)很多的話,hive.exec.max.dynamic.partitions.pernode也需要設置為一個較大的數(shù),否則會有報錯提醒。

現(xiàn)在有sql

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

可以看出,Hive根據(jù)select語句中最后兩列來確定分區(qū)字段countrystate的值,這里刻意使用了不同的命名,就是為了強調(diào)源表字段和輸出分區(qū)值之間的關(guān)系是根據(jù)位置而不是根據(jù)命名來匹配的。

動靜分區(qū)結(jié)合

也可以混合使用動態(tài)和靜態(tài)分區(qū)。上面那個例子,我們可以指定國家這個分區(qū)值五為靜態(tài)值US,而分區(qū)字段state是動態(tài)值:

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

注意:靜態(tài)分區(qū)需要出現(xiàn)在動態(tài)分區(qū)字段之前。

動態(tài)分區(qū)功能默認情況下是沒有開啟的,默認是以嚴格模式執(zhí)行,這種模式下要求至少有一列分區(qū)字段是靜態(tài)的。這樣做的好處是可以防止因設計或其它錯誤查詢導致產(chǎn)生大量的分區(qū),比如sql boy不小心使用了時間戳作為分區(qū)字段,那將是災難。在日常導入一天的數(shù)據(jù),通常是指定日期為靜態(tài)分區(qū),小時為動態(tài)分區(qū),進行混合模式導入。

例子

建表

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;
SQL

導入數(shù)據(jù)到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
SQL

利用動態(tài)分區(qū)插入

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

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




作者:柯廣的網(wǎng)絡日志

微信公眾號:Java大數(shù)據(jù)與數(shù)據(jù)倉庫