1. 程式人生 > >Hive中的分桶概念的學習以及示例分析學習

Hive中的分桶概念的學習以及示例分析學習

我們學習一下分桶表,其實分割槽和分桶這兩個概念對於初學者來說是比較難理解的。但對於理解了的人來說,發現又是如此簡單。

我們先建立一個分桶表,並嘗試直接上傳一個數據

create table student4(sno int,sname string,sex string,sage int, sdept string) clustered by(sno) into 3 buckets row format delimited fields terminated by ',';
set hive.enforce.bucketing = true;強制分桶。
load data local inpath '/home/hadoop/hivedata/students.txt' overwrite into table student4;

 

我們看到雖然設定了強制分桶,但實際student表下面只有一個students一個檔案。分桶也就是分割槽,分割槽數量等於檔案數,所以上面方法並沒有分桶。

現在,我們用插入的方法給另外一個分桶表傳入同樣資料

複製程式碼

create table student4(sno int,sname string,sex string,sage int, sdept string) clustered by(sno) into 3 buckets row format delimited fields terminated by ',';
set hive.enforce.bucketing = true;強制分桶。
load data local inpath '/home/hadoop/hivedata/students.txt' overwrite into table student4;
我們看到雖然設定了強制分桶,但實際STUDENT表下面只有一個STUDENTS一個檔案。
分桶也就是分割槽,分割槽數量等於檔案數,所以上面方法並沒有分桶。
#建立第2個分桶表
create table stu_buck(sno int,sname string,sex string,sage int,sdept string)
clustered by(sno) 
sorted by(sno DESC)
into 4 buckets
row format delimited
fields terminated by ',';

#設定變數,設定分桶為true, 設定reduce數量是分桶的數量個數
set hive.enforce.bucketing = true;
set mapreduce.job.reduces=4;
#開會往建立的分通表插入資料(插入資料需要是已分桶, 且排序的)
#可以使用distribute by(sno) sort by(sno asc)   或是排序和分桶的欄位相同的時候使用Cluster by(欄位)
#注意使用cluster by  就等同於分桶+排序(sort)
insert into table stu_buck
select sno,sname,sex,sage,sdept from student distribute by(sno) sort by(sno asc);

Query ID = root_20171109145012_7088af00-9356-46e6-a988-f1fc5f6d2e13
Total jobs = 1
Launching Job 1 out of 1
Number of reduce tasks determined at compile time: 4
In order to change the average load for a reducer (in bytes):
  set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
  set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
  set mapreduce.job.reduces=<number>
Starting Job = job_1510197346181_0014, Tracking URL = http://server71:8088/proxy/application_1510197346181_0014/
Kill Command = /usr/local/hadoop/bin/hadoop job  -kill job_1510197346181_0014
Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 4
2017-11-09 14:50:59,642 Stage-1 map = 0%,  reduce = 0%
2017-11-09 14:51:38,682 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 5.04 sec
2017-11-09 14:52:31,935 Stage-1 map = 100%,  reduce = 50%, Cumulative CPU 7.91 sec
2017-11-09 14:52:33,467 Stage-1 map = 100%,  reduce = 67%, Cumulative CPU 15.51 sec
2017-11-09 14:52:39,420 Stage-1 map = 100%,  reduce = 83%, Cumulative CPU 22.5 sec
2017-11-09 14:52:40,953 Stage-1 map = 100%,  reduce = 92%, Cumulative CPU 25.86 sec
2017-11-09 14:52:42,243 Stage-1 map = 100%,  reduce = 100%, Cumulative CPU 28.01 sec
MapReduce Total cumulative CPU time: 28 seconds 10 msec
Ended Job = job_1510197346181_0014
Loading data to table default.stu_buck
Table default.stu_buck stats: [numFiles=4, numRows=22, totalSize=527, rawDataSize=505]
MapReduce Jobs Launched: 
Stage-Stage-1: Map: 1  Reduce: 4   Cumulative CPU: 28.01 sec   HDFS Read: 18642 HDFS Write: 819 SUCCESS
Total MapReduce CPU Time Spent: 28 seconds 10 msec
OK
Time taken: 153.794 seconds 

複製程式碼

我們設定reduce的數量為4,學過mapreduce的人應該知道reduce數等於分割槽數,也等於處理的檔案數量。

把表或分區劃分成bucket有兩個理由

1,更快,桶為表加上額外結構,連結相同列劃分了桶的表,可以使用map-side join更加高效。

2,取樣sampling更高效。沒有分割槽的話需要掃描整個資料集。

hive> create table bucketed_user (id int,name string)

> clustered by (id) sorted by (id asc) into 4 buckets;

重點1:CLUSTERED BY來指定劃分桶所用列和劃分桶的個數。HIVE對key的hash值除bucket個數取餘數,保證資料均勻隨機分佈在所有bucket裡。

重點2:SORTED BY對桶中的一個或多個列另外排序

總結:我們發現其實桶的概念就是MapReduce的分割槽的概念,兩者完全相同。物理上每個桶就是目錄裡的一個檔案,一個作業產生的桶(輸出檔案)數量和reduce任務個數相同。

而分割槽表的概念,則是新的概念。分割槽代表了資料的倉庫,也就是資料夾目錄。每個資料夾下面可以放不同的資料檔案。通過資料夾可以查詢裡面存放的檔案。但資料夾本身和資料的內容毫無關係。

桶則是按照資料內容的某個值進行分桶,把一個大檔案雜湊稱為一個個小檔案。

這些小檔案可以單獨排序。如果另外一個表也按照同樣的規則分成了一個個小檔案。兩個表join的時候,就不必要掃描整個表,只需要匹配相同分桶的資料即可。效率當然大大提升。

同樣,對資料抽樣的時候,也不需要掃描整個檔案。只需要對每個分割槽按照相同規則抽取一部分資料即可。

轉載於: