文章目錄
Hive分桶:-Buckets
一:爲什麼要分桶?:–對數據的垂直切分解決方案
問這個前提是因爲我們已經有分區了,爲什麼又分桶呢?
分區提供了一個隔離數據和優化查詢的便利方式,不過並非所有的數據都可形成合理的分區,尤其是需要確定合適大小的分區劃分方式。
(總會有有的數據分區劃分方式不合理,且沒有更好的劃分區的特徵名了,可能導致有的分區數據過多,而某些分區沒有什麼數據的尷尬情況)
分桶是將數據集分解爲更容易管理的更細粒度劃分的另一種技術。
二:分桶有什麼用?:
-
更高的查詢處理效率(join)----(實際使用還沒有感受這麼深刻)
Hive 在處理有些查詢時能利用這個結構。具體而言,連接兩個在(包含連接列的)相同列上劃分了桶的表,可以使用 Map 端連接 (Map-side join)高效的實現。比如JOIN操作。對於JOIN操作兩個表有一個相同的列,如果對這兩個表都進行了桶操作。那麼將保存相同列值的桶進行JOIN操作就可以,可以大大較少JOIN的數據量。
-
使抽樣(sampling)更高效
三:分桶遵循什麼原理?
跟MR的HashPartitioner原理一樣
- MR是通過key的hash值 / 設置reduceTask的個數 來取模獲取分區
- Hive按照分桶字段的hash值 / 設置的分桶的個數 來取模獲取分桶
當我們分區之後若是列值的區域還不夠細分,我們將在分區的基礎上,對列值再次進行分桶,通過對列值做Hash,然後除以設置的桶的個數求餘來決定哪條記錄存放在哪個桶裏。
四:怎麼分桶?:
第一步:創建分桶表:
create table xxx(
employee string
)
clustered by (employee_id) into 2 buckets
注意點:
-
分桶列必須是表中
已有列
,而分區不用 -
分桶數是2的n次方
因爲分桶底層是hash表,取模操作太慢,我們是直接二進制與操作,當是2的n次方時,它與哈希值的與操作,對於存儲數組在哪個下標的位置的控制權才能全權交給hash值得二進制來控制,並且剛好將hash值映射到數組下標範圍,沒有超出。
-
直接分文件,不是分文件夾
- 分桶將表中的數據拆分到不同的文件中,解耦操作
- 分區將表中的數據邏輯化分到不同文件夾(區域)中
第二步:設置分桶規則:
因爲分桶與MR的partition異曲同工,最後產生的文件數是由taskReduce來決定的,所以最後的reduce數量最好一定要和邏輯劃分的分桶數量相等,不然可能出現一個reduce處理多個桶,導致產生的文件裏有多個桶的數據。
-- 設置嚴格分桶模式
set hive.strict.checks.bucketing = true;
-- 開啓強制分桶模式,會將reduce數量變成分桶的數量個數
set hive.enforce.bucketing=true;
第三步:必須用insert方式加載數據:(除非你把嚴格分桶模式關閉)
# 導表時一定要注意,導的表與目的地表的列名一致
insert into table xxx select employee_id from yyy;
五:都是爲了提高查找效率,索引和分桶和分區?
索引和分區最大的區別
就是索引不分割數據庫,分區分割數據庫。
索引其實就是拿額外的存儲空間換查詢時間,但分區已經將整個大數據庫按照分區列拆分成多個小數據庫了。
分區和分桶最大的區別
就是分桶隨機分割數據庫,分區是非隨機分割數據庫。
因爲分桶是按照列的哈希函數進行分割的,相對比較平均;而分區是按照列的值來進行分割的,容易造成數據傾斜。
其次兩者的另一個區別就是分桶是對應不同的文件(細粒度),分區是對應不同的文件夾(粗粒度)。
注意:普通表(外部表、內部表)、分區表這三個都是對應HDFS上的目錄,桶表對應是目錄裏的文件