Hive學習筆記——Hive中的分桶


對於每一個表(table)或者分區, Hive可以進一步組織成桶,也就是說桶是更為細粒度的數據范圍划分。Hive也是針對某一列進行桶的組織。Hive采用對列值哈希,然后除以桶的個數求余的方式決定該條記錄存放在哪個桶當中。

把表(或者分區)組織成桶(Bucket)有兩個理由:

(1)獲得更高的查詢處理效率。桶為表加上了額外的結構,Hive 在處理有些查詢時能利用這個結構。具體而言,連接兩個在(包含連接列的)相同列上划分了桶的表,可以使用 Map 端連接 (Map-side join)高效的實現。比如JOIN操作。對於JOIN操作兩個表有一個相同的列,如果對這兩個表都進行了桶操作。那么將保存相同列值的桶進行JOIN操作就可以,可以大大較少JOIN的數據量。

(2)使取樣(sampling)更高效。在處理大規模數據集時,在開發和修改查詢的階段,如果能在數據集的一小部分數據上試運行查詢,會帶來很多方便。

按我的理解,所謂Hive中的分桶,實際就是指的MapReduce中的分區。根據Reduce的數量,分成不同個數的文件。

我們以一個demo進行說明。

創建分桶表

drop table stu_buck;
create table stu_buck(id int, name string, score double)
clustered by(id) into 4 buckets
row format delimited
fields terminated by ',';

設置變量,設置分桶為true, 設置reduce數量是分桶的數量個數

set hive.enforce.bucketing = true;
set mapreduce.job.reduces=4;

 

我們從另外一個表student查詢數據放到該表中,student中的表數據如下:

開始往創建的分桶表插入數據(插入數據需要是已分桶, 且排序的)

可以使用distribute by(id) sort by(id asc)

排序和分桶的字段相同的時候也可以使用Cluster by(字段)

注意使用cluster by 就等同於分桶+排序(sort)

可以嘗試以下幾種方式:

insert into table stu_buck
select id,name,score from student distribute by(id) sort by(id asc);

insert overwrite table stu_buck
select id,name,score from student distribute by(id) sort by(id asc);

insert overwrite table stu_buck
select id,name,score from student cluster by(id);

insert overwrite table stu_buck
select id,name,score from student cluster by(id) sort by(id); 報錯,cluster 和 sort 不能共存

 

效果:

 

我們來查看以下文件的內容:

dfs -cat /user/hive/warehouse/test.db/stu_buck/000000_0;

dfs -cat /user/hive/warehouse/test.db/stu_buck/000001_0;

dfs -cat /user/hive/warehouse/test.db/stu_buck/000002_0;

dfs -cat /user/hive/warehouse/test.db/stu_buck/000003_0;

 

 

注:1、order by 會對輸入做全局排序,因此只有一個reducer,會導致當輸入規模較大時,需要較長的計算時間。
2、sort by不是全局排序,其在數據進入reducer前完成排序。因此,如果用sort by進行排序,並且設置mapred.reduce.tasks>1,則sort by只保證每個reducer的輸出有序,不保證全局有序。
3、distribute by(字段)根據指定的字段將數據分到不同的reducer,且分發算法是hash散列。
4、Cluster by(字段) 除了具有Distribute by的功能外,還會對該字段進行排序。
5、創建分桶表並不意味着load進數據也是分桶的,你必須先分好桶,然后再放到表中。


因此,如果分桶和sort字段是同一個時,此時,cluster by = distribute by + sort by

分桶表的作用:最大的作用是用來提高join操作的效率;但是兩者的分桶數要相同或者成倍數。

為什么可以提高join操作的效率呢?因為按照MapReduce的分區算法,是Id的HashCode值模上ReduceTaskNumbers,所以一個ID會分到同一個桶中,這樣合並就不用整個表遍歷求笛卡爾積了,對應的桶合並就可以了。

 


免責聲明!

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



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