Hive系列(三)Hive分區後數據仍劃分不均??Hive分桶教你怎麼解決

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上的目錄,桶表對應是目錄裏的文件

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章