hive中的桶


hive中有桶的概念,對於每一個表或者分區,可以進一步組織成桶,說白點,就是更細粒度的數據范圍。
hive采用列值哈希,然后除以桶的個數以求余的方式決定該條記錄存放在哪個桶當中。
使用桶的好處:
1、獲得更高的查詢處理效率。桶為表加上了額外的結構,Hive在處理有些查詢時能利用這個結構。具體而言,連接兩個在(包含連接列的)相同列上划分了桶的表,可以使用 Map 端連接 (Map-side join)高效的實現。比如JOIN操作。對於JOIN操作兩個表有一個相同的列,如果對這兩個表都進行了桶操作。那么將保存相同列值的桶進行JOIN操作就可以,可以大大較少JOIN的數據量。
2、使取樣(sampling)更高效。在處理大規模數據集時,在開發和修改查詢的階段,如果能在數據集的一小部分數據上試運行查詢,會帶來很多方便。

需要特別注意的是:clustered by和sorted by不會影響數據的導入,這意味着,用戶必須自己負責數據如何如何導入,包括數據的分桶和排序。
可以使用'set hive.enforce.bucketing = true'

可以自動控制上一輪reduce的數量從而適配bucket的個數,

看個例子

原始數據

1	15	xiaohong
2	16	xiaoming
3	17	xiaohuang
3	18	xiaocui
4	19	xiaoma
5	21	xiaocai
6	22	xiaojie
7	25	xiaoliu
8	28	xaoqi

先創建一張普通表,再創建一張桶的表。

create table student(id INT, age INT, name STRING)
partitioned by(p_date STRING) 
row format delimited fields terminated by '\t';

create table  bucketed_student(id INT, age INT, name STRING)
partitioned by(stat_date STRING) 
clustered by(id) sorted by(age) into 2 bucket
row format delimited fields terminated by '\t';

load數據到普通表,因為直接load到分桶的表是不會分桶,需要insert進行才會根據根據分桶要求進行分桶。

LOAD DATA LOCAL INPATH '/home//aaa' OVERWRITE INTO table bucketed_student partition(p_date='2016');
 
set hive.enforce.bucketing = true;
insert overwrite table bucketed_student partition(p_date='2016') select id,age,name from student where p_date=2016

查看兩表的目錄,發現分桶會生成兩份數據文件

hadoop fs -ls /data/hive/warehouse/temp.db/bucketed_student/p_date=2016
Found 2 items
-rwxr-xr-x   3 webopa hive         50 2016-11-23 13:53 /data/hive/warehouse/temp.db/bucketed_student/p_date=2016/000000_0
-rwxr-xr-x   3 webopa hive         68 2016-11-23 13:53 /data/hive/warehouse/temp.db/bucketed_student/p_date=2016/000001_0

普通表是一份

hadoop fs -ls /data/hive/warehouse/temp.db/student/p_date=2016
Found 1 items
-rwxrwxrwx   3 webopa hive        117 2016-11-23 11:41 /data/hive/warehouse/temp.db/student/p_date=2016/aaa

查看下分通表每個文件中的數據。偶數一個文件,基數一個文件。

hadoop fs -cat /data/hive/warehouse/temp.db/bucketed_student/p_date=2016/000000_0
8	28	xaoqi
6	22	xiaojie
4	19	xiaoma
2	16	xiaoming
hadoop fs -cat /data/hive/warehouse/temp.db/bucketed_student/p_date=2016/000001_0
7	25	xiaoliu
5	21	xiaocai
3	18	xiaocui
3	17	xiaohuang
1	15	xiaohong

 查看sampling數據:

select * from bucketed_student  tablesample(bucket 1 out of 2 on id); 
8	28	xaoqi	2016
6	22	xiaojie	2016
4	19	xiaoma	2016
2	16	xiaoming	2016

tablesample是抽樣語句,語法:TABLESAMPLE(BUCKET x OUT OF y)
y必須是table總bucket數的倍數或者因子。hive根據y的大小,決定抽樣的比例。例如,table總共分了64份,當y=32時,抽取 (64/32=)2個bucket的數據,當y=128時,抽取(64/128=)1/2個bucket的數據。x表示從哪個bucket開始抽取。例 如,table總bucket數為32,tablesample(bucket 3 out of  16),表示總共抽取(32/16=)2個bucket的數據,分別為第3個bucket和第(3+16=)19個bucket的數據


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM