Hadoop Hive概念學習系列之hive里的桶(十一)


      

 

  不多說,直接上干貨!

 

 

 Hive還可以把表或分區,組織成桶。將表或分區組織成桶有以下幾個目的:

  第一個目的是為看取樣更高效,因為在處理大規模的數據集時,在開發、測試階段將所有的數據全部處理一遍可能不太現實,這時取樣就必不可少。

  第二個目的是為了獲得更好的查詢處理效率。

 

        桶為了表提供了額外的結構,Hive在處理某些查詢時利用這個結構,能給有效地提高查詢效率。

        桶是通過對指定列進行哈希計算來實現的,通過哈希值將一個列名下的數據切分為一組桶,並使每個桶對應於該列名下的一個存儲文件

 

 

    在建立桶之前,需要設置hive.enforce.bucketing屬性為true,使得hive能識別桶。

  以下為創建帶有桶的表的語句:

CREATE TABLE bucketed_user(
id INT,
name String
)
CLUSTERED BY (id) INTO 4 BUCKETS;

   向桶中插入數據,這里按照用戶id分成了4個桶,在插入數據時對應4個reduce操作,輸出4個文件。

 

 

 

  分區中的數據可以被進一步拆分成桶,bucket,不同於分區對列直接進行拆分,桶往往使用列的哈希值進行數據采樣。

在分區數量過於龐大以至於可能導致文件系統崩潰時,建議使用桶。

  桶的數量是固定的。

  Hive使用基於列的哈希函數對數據打散,並分發到各個不同的桶中從而完成數據的分桶過程。

  注意,hive使用對分桶所用的值進行hash,並用hash結果除以桶的個數做取余運算的方式來分桶保證了每個桶中都有數據,但每個桶中的數據條數不一定相等

  哈希函數的選擇依賴於桶操作所針對的列的數據類型。除了數據采樣,桶操作也可以用來實現高效的Map端連接操作。

   記住,分桶比分區,更高的查詢效率

 

 

 

如何進行桶操作?

  例子1

1、創建臨時表 student_tmp,並導入數據。

hive> desc student_tmp;
hive> select * from student_tmp;

 

 


2、創建 student 表。經過分區操作過后的表已經被拆分成2個桶。

create table 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 ',';

 

  分區中的數據可以被進一步拆分成桶!!!正確理解

  所有,桶,先partitioned by (stat_date string)

      ,再,clustered by (id) sorted by(age) into 2 bucket

 

 

3、設置環境變量。

hive> set hive.enforce.bucketing=true;

 

 


4、插入數據

hive> from student_tmp
insert overwrite table student partition(stat_date='2015-01-19')
select id,age,name where stat_date='2015-01-18' sort by age;

 

  這都是固定的格式,一環扣一環的。


5、查看文件目錄
$ hadoop fs -ls /usr/hive/warehouse/student/stat_date=2015-01-19/


6、查看 sampling 數據。
tablesample 是抽樣語句,語法如下
tablesample(bucket x out of y)
y 必須是 table 中 BUCKET 總數的倍數或者因子。

 

 

 

 

 

 

例子2

  在下面的例子中,經過分區操作過后的表已經被拆分成100個桶。

CREATE EXTERNAL TABLE videos_b(
prodicer string,
title string,
category string
)
PARTITIONED BY(year int) CLUSTERED BY(title)INTO 100 BUCKETS;

 

 

  現在,我們開始填充這張帶桶操作的表:

set hive.enfirce.bucketinig=true;
FROM videos
INSERT OVERWRITE TABLE videos_b
PARTITION(year=1999)
SELECT producer,title,string WHERE year=2009;

 

 

  如果不使用set hive.enforce.bucketing=true這項屬性,我們需要顯式地聲明set mapred.reduce.tasks=100來設置Reducer的數量。

此外,還需要在SELECT語句后面加上CLUSTERBY來實現INSERT查詢。

  下面是不使用桶設置的例子:

set mapred.reduce.tasks=100;
FROM videos
INSERT OVERWRITE TABLE videos_b
PARTITION(year=1999)
SELECT producer,title,string WHERE year=2009 CLUSTER BY title;

 

 

 

在Hive的文檔中可以找到有關桶的更多細節:

https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL

 


免責聲明!

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



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