Hive分桶之BUCKET详解
Bucket
 1.對(duì)于每一個(gè)表(table)或者分區(qū)(partition), Hive可以進(jìn)一步組織成桶,也就是說(shuō)桶是更為細(xì)粒度的數(shù)據(jù)范圍劃分。Hive也是 針對(duì)某一列進(jìn)行桶的組織。Hive采用對(duì)列值哈希,然后除以桶的個(gè)數(shù)求余的方式?jīng)Q定該條記錄存放在哪個(gè)桶當(dāng)中。
2,把表(或者分區(qū))組織成桶(Bucket)有兩個(gè)理由:
 (1)獲得更高的查詢處理效率。桶為表加上了額外的結(jié)構(gòu),Hive 在處理有些查詢時(shí)能利用這個(gè)結(jié)構(gòu)。
 具體而言,連接兩個(gè)在(包含連接列的)相同列上劃分了桶的表,可以使用 Map 端連接 (Map-side join)高效的實(shí)現(xiàn)。
 比如JOIN操作。對(duì)于JOIN操作兩個(gè)表有一個(gè)相同的列,如果對(duì)這兩個(gè)表都進(jìn)行了桶操作。
 那么將保存相同列值的桶進(jìn)行JOIN操作就可以,可以大大較少JOIN的數(shù)據(jù)量。
 (2)使取樣(sampling)更高效。在處理大規(guī)模數(shù)據(jù)集時(shí),在開發(fā)和修改查詢的階段,
 如果能在數(shù)據(jù)集的一小部分?jǐn)?shù)據(jù)上試運(yùn)行查詢,會(huì)帶來(lái)很多方便。
 下面來(lái)一個(gè)例子:
下面load數(shù)據(jù):
 插入數(shù)據(jù)之前需要設(shè)置參數(shù)hive.enforce.bucketing=true,以強(qiáng)制hive的reducer數(shù)目為分桶數(shù)。
 如果不設(shè)置這個(gè)hive參數(shù),最后的桶個(gè)數(shù)可能不是建表語(yǔ)句中的個(gè)數(shù)。
 另外,也可以通過將參數(shù)mapred.reduce.tasks設(shè)置為桶的數(shù)目來(lái)控制reducer的數(shù)目,建議采用第一種方式。
物理上,每個(gè)桶就是表(或分區(qū))目錄里的一個(gè)文件。它的文件名并不重要,但是桶 n 是按照字典序排列的第 n 個(gè)文件。
 事實(shí)上,桶對(duì)應(yīng)于 MapReduce 的輸出文件分區(qū):一個(gè)作業(yè)產(chǎn)生的桶(輸出文件)和reduce任務(wù)個(gè)數(shù)相同。
我們可以通過查看剛才 創(chuàng)建的bucketd_users表的布局來(lái)了解這一情況。運(yùn)行如下命令:
查看表的結(jié)構(gòu): hive> dfs -ls /user/hive/warehouse/dz_test; 將顯示有4個(gè)新建的文件。文件名如下(文件名包含時(shí)間戳,由Hive產(chǎn)生,因此 每次運(yùn)行都會(huì)改變): attempt_201701221636_0016_r_000000_0 attempt_201701221636_0016_r-000001_0 attempt_201701221636_0016_r_000002_0 attempt_201701221636_0016_r_000003_0 第一個(gè)桶里包括用戶ID和4,因?yàn)橐粋€(gè)INT的哈希值就是這個(gè)整數(shù)本身,在這里 除以桶數(shù)(4)以后的余數(shù):2 讀取數(shù)據(jù),看每一個(gè)文件的數(shù)據(jù): hive> dfs -cat /user/hive/warehouse/dz_test/*0_0; 0 Nat 4 Ann 用TABLESAMPLE子句對(duì)表進(jìn)行取樣,我們可以獲得相同的結(jié)果。這個(gè)子句會(huì)將 查詢限定在表的一部分桶內(nèi),而不是使用整個(gè)表: . 對(duì)桶中的數(shù)據(jù)進(jìn)行采樣: hive> SELECT * FROM dz_test >TABLESAMPLE(BUCKET 1 OUT OF 4 ON id); 0 Nat 4 Ann 桶的個(gè)數(shù)從1開始計(jì)數(shù)。因此,前面的查詢從4個(gè)桶的第一個(gè)中獲取所有的用戶。 對(duì)于一個(gè)大規(guī)模的、均勻分布的數(shù)據(jù)集,這會(huì)返回表中約四分之一的數(shù)據(jù)行。 我們也可以用其他比例對(duì)若干個(gè)桶進(jìn)行取樣(因?yàn)槿硬⒉皇且粋€(gè)精確的操作,因此這個(gè) 比例不一定要是桶數(shù)的整數(shù)倍)。 例如,下面的查詢返回一半的桶: 7. 查詢一半返回的桶數(shù): hive> SELECT * FROM dz_test > TABLESAMPLE(BUCKET 1 OUT OF 2 ON id); 0 Nat 4 Ann 2 Joe 因?yàn)椴樵冎恍枰x取和TABLESAMPLE子句匹配的桶,所以取樣分桶表是非常高效 的操作。 如果使用rand()函數(shù)對(duì)沒有劃分成桶的表進(jìn)行取樣,即使只需要讀取很 小一部分樣本,也要掃描整個(gè)輸入數(shù)據(jù)集: hive〉 SELECT * FROM dz_test > TABLESAMPLE(BUCKET 1 OUT OF 4 ON rand()); 2 Doe ①?gòu)腍ive 0.6.0開始,對(duì)以前的版本,必須把mapred.reduce .tasks設(shè)為表中要填 充的桶的個(gè)數(shù)。 如果桶是排序的,還需要把hive.enforce.sorting設(shè)為true。 ②顯式原始文件時(shí),因?yàn)榉指糇址且粋€(gè)不能打印的控制字符,因此字段都擠在一起。https://blog.csdn.net/m0_37534613/article/details/55258928
總結(jié)
以上是生活随笔為你收集整理的Hive分桶之BUCKET详解的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: vue实现表格单元格的拆分、合并
 - 下一篇: pass by value 与pass