Hive_ 对比分区,分桶
Hive 動態(tài)分區(qū)
建表時指出分區(qū)字段,但不給值,導(dǎo)入數(shù)據(jù)時 hive 根據(jù)分區(qū)字段的值自動創(chuàng)建分區(qū)。
開啟動態(tài)分區(qū)需要修改一些配置:
是否開啟動態(tài)分區(qū),默認(rèn):false
set hive.exec.dynamic.partition=true;
動態(tài)分區(qū)模式,默認(rèn):strict:嚴(yán)格模式,至少有一個分區(qū)列是靜態(tài)分區(qū)
set hive.exec.dynamic.partition.mode=nostrict;
相關(guān)參數(shù):
每一個執(zhí)行 mr 節(jié)點上,允許創(chuàng)建的動態(tài)分區(qū)的最大數(shù)量(100)
set hive.exec.max.dynamic.partitions.pernode;
所有執(zhí)行 mr 節(jié)點上,允許創(chuàng)建的所有動態(tài)分區(qū)的最大數(shù)量(1000)
set hive.exec.max.dynamic.partitions;
所有的 mr job 允許創(chuàng)建的文件的最大數(shù)量(100000)
set hive.exec.max.created.files;
hive> set hive.exec.dynamic.partition=true;
hive> set hive.exec.dynamic.partition.mode=nostrict;
hive> create table part0 (
id int,
name string
)
PARTITIONED BY (sex string)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ',';
hive> desc part0;
col_name data_type ?comment
id int
name string
sex string
# Partition Information
# col_name data_type comment
sex string
導(dǎo)入兩個分區(qū)的數(shù)據(jù)
hive> load data local inpath '/root/part0_data' into table part0 PARTITION (sex='1');
hive> load data local inpath '/root/part0_data' into table part0 PARTITION (sex='2');
hive> select * from part0;
part0.id part0.name ?part0.sex
1 ?Jed 1
2 ?Tom 1
3 ?Cat 1
1 ?Jed 2
2 ?Tom 2
3 ?Cat 2
創(chuàng)建一個和 part0 表機(jī)構(gòu)完全相同的表 part1
hive> create table part1 like part0;
給 part1 導(dǎo)入數(shù)據(jù),使用動態(tài)分區(qū)
hive> from part0
insert into table part1 partition (sex)
select *;
hive> select * from part1;
part1.id part1.name ?part1.sex
1 ?Jed 1
2 ?Tom 1
3 ?Cat 1
1 ?Jed 2
2 ?Tom 2
3 ?Cat 2
使用動態(tài)分區(qū)導(dǎo)入數(shù)據(jù)時,不使用 load,因為 load 必須指定分區(qū)的值,應(yīng)該使用
from+select 方式。
Hive 分桶
分桶表是對列值取哈希值的方式,將不同數(shù)據(jù)放到不同文件中存儲。對于 hive 中每一
個表、分區(qū)都可以進(jìn)一步進(jìn)行分桶。由列的哈希值除以桶的個數(shù)來決定每條數(shù)據(jù)劃分在哪
個桶中。比分區(qū)更加細(xì)粒度。
適用場景:數(shù)據(jù)抽樣( sampling )、map-join
開啟分桶支持:
set hive.enforce.bucketing=true;
默認(rèn):false。設(shè)置為 true 之后,mr 運(yùn)行時會根據(jù) bucket 的個數(shù)自動分配 reduce task
個數(shù)。(用戶也可以通過 mapred.reduce.tasks 自己設(shè)置 reduce 任務(wù)個數(shù),但分桶時不推薦
使用)注意:一次作業(yè)產(chǎn)生的桶(文件數(shù)量)和 reduce task 個數(shù)一致。
hive> set hive.enforce.bucketing=true;
創(chuàng)建分桶表
hive> CREATE TABLE bucket(id int, name string, age int)
CLUSTERED BY (age) INTO 4 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
查看表結(jié)構(gòu)(比 desc table;更詳細(xì))
hive> desc formatted bucket;
hive> from bucket_test
insert into table bucket
select *;
hive> select * from bucket;
bucket.id bucket.name bucket.age
1 ?Tom 11
2 ?Cat 22
3 ?Dog 33
4 ?Tony 44
5 ?Bob 55
6 ?Hive 66
7 ?Hadoop 77
8 ?Java 88
注意:使用 load 加載數(shù)據(jù)不會出現(xiàn)分桶的效果
[root@node03 ~]# hdfs dfs -cat /user/hive/warehouse/bucket/000000_0
8,Java,88
4,Tony,44
[root@node03 ~]# hdfs dfs -cat /user/hive/warehouse/bucket/000001_0
7,Hadoop,77
3,Dog,33
抽樣查詢
TABLESAMPLE 語法:TABLESAMPLE(BUCKET x OUT OF y)
x:表示從哪個 bucket 開始抽取數(shù)據(jù)
y:必須為該表總 bucket 數(shù)的倍數(shù)或因子
共抽取(bucketNum/y)個桶的數(shù)據(jù),抽取第 x,和第(y+(bucketNum/y))個桶中的數(shù)據(jù)
例如:
TABLESAMPLE(BUCKET 2 OUT OF 16) 桶總數(shù)為 32
共抽取 2(32/16)個桶的數(shù)據(jù),抽取第 2(x),和第 18(y+32/16)個桶中的數(shù)據(jù)
TABLESAMPLE(BUCKET 3 OUT OF 256) 桶總數(shù)為 32
共抽取 0.125(32/256)個桶的數(shù)據(jù),抽取第 3(x)個桶的 1/8 數(shù)據(jù)
hive> select id, name, age
from bucket
tablesample(bucket 2 out of 4 on age);#取第二個桶
id ?name ?age
7 ?Hadoop 77
3 ?Dog 33
小結(jié):
分區(qū)針對的是數(shù)據(jù)的存儲路徑;分桶針對的是數(shù)據(jù)文件。
分區(qū)提供一個隔離數(shù)據(jù)和優(yōu)化查詢的便利方式。不過,并非所有的數(shù)據(jù)集都可形成合理的分區(qū),特別是之前所提到過的要確定合適的劃分大小這個疑慮。
分桶是將數(shù)據(jù)集分解成更容易管理的若干部分的另一個技術(shù)。
?
總結(jié)
以上是生活随笔為你收集整理的Hive_ 对比分区,分桶的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: map和mapValues的纠纷
- 下一篇: Spark读取文本文件并转换为DataF