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的時候,就不必要掃描整個表,只需要匹配相同分桶的資料即可。效率當然大大提升。
同樣,對資料抽樣的時候,也不需要掃描整個檔案。只需要對每個分割槽按照相同規則抽取一部分資料即可。
轉載於: