Hive_ 对比分区,分桶
Hive 動態分區
建表時指出分區字段,但不給值,導入數據時 hive 根據分區字段的值自動創建分區。
開啟動態分區需要修改一些配置:
是否開啟動態分區,默認:false
set hive.exec.dynamic.partition=true;
動態分區模式,默認:strict:嚴格模式,至少有一個分區列是靜態分區
set hive.exec.dynamic.partition.mode=nostrict;
相關參數:
每一個執行 mr 節點上,允許創建的動態分區的最大數量(100)
set hive.exec.max.dynamic.partitions.pernode;
所有執行 mr 節點上,允許創建的所有動態分區的最大數量(1000)
set hive.exec.max.dynamic.partitions;
所有的 mr job 允許創建的文件的最大數量(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
導入兩個分區的數據
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
創建一個和 part0 表機構完全相同的表 part1
hive> create table part1 like part0;
給 part1 導入數據,使用動態分區
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
使用動態分區導入數據時,不使用 load,因為 load 必須指定分區的值,應該使用
from+select 方式。
Hive 分桶
分桶表是對列值取哈希值的方式,將不同數據放到不同文件中存儲。對于 hive 中每一
個表、分區都可以進一步進行分桶。由列的哈希值除以桶的個數來決定每條數據劃分在哪
個桶中。比分區更加細粒度。
適用場景:數據抽樣( sampling )、map-join
開啟分桶支持:
set hive.enforce.bucketing=true;
默認:false。設置為 true 之后,mr 運行時會根據 bucket 的個數自動分配 reduce task
個數。(用戶也可以通過 mapred.reduce.tasks 自己設置 reduce 任務個數,但分桶時不推薦
使用)注意:一次作業產生的桶(文件數量)和 reduce task 個數一致。
hive> set hive.enforce.bucketing=true;
創建分桶表
hive> CREATE TABLE bucket(id int, name string, age int)
CLUSTERED BY (age) INTO 4 BUCKETS
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
查看表結構(比 desc table;更詳細)
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 加載數據不會出現分桶的效果
[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 開始抽取數據
y:必須為該表總 bucket 數的倍數或因子
共抽取(bucketNum/y)個桶的數據,抽取第 x,和第(y+(bucketNum/y))個桶中的數據
例如:
TABLESAMPLE(BUCKET 2 OUT OF 16) 桶總數為 32
共抽取 2(32/16)個桶的數據,抽取第 2(x),和第 18(y+32/16)個桶中的數據
TABLESAMPLE(BUCKET 3 OUT OF 256) 桶總數為 32
共抽取 0.125(32/256)個桶的數據,抽取第 3(x)個桶的 1/8 數據
hive> select id, name, age
from bucket
tablesample(bucket 2 out of 4 on age);#取第二個桶
id ?name ?age
7 ?Hadoop 77
3 ?Dog 33
小結:
分區針對的是數據的存儲路徑;分桶針對的是數據文件。
分區提供一個隔離數據和優化查詢的便利方式。不過,并非所有的數據集都可形成合理的分區,特別是之前所提到過的要確定合適的劃分大小這個疑慮。
分桶是將數據集分解成更容易管理的若干部分的另一個技術。
?
總結
以上是生活随笔為你收集整理的Hive_ 对比分区,分桶的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: map和mapValues的纠纷
- 下一篇: Spark读取文本文件并转换为DataF