2013-10-02 62 views

回答

186

分區數據通常用於水平分配負載,這具有性能優勢,並有助於以邏輯方式組織數據。 示例:如果我們正在處理大型employee表,並且經常使用WHERE子句將查詢限制爲特定國家或部門的查詢。對於更快的查詢響應Hive表可以是PARTITIONED BY (country STRING, DEPT STRING)。分區表的變化如何蜂巢結構中的數據存儲和蜂巢現在將創建反映分區結構子目錄像

... /員工/ 國家= ABC/DEPT = XYZ

如果員工的查詢限制爲country=ABC,它只會掃描一個目錄country=ABC的內容。這可以顯着提高查詢性能,但前提是分區方案反映常見的過濾。分區功能在Hive中非常有用,但是,創建分區過多的設計可能會優化某些查詢,但對其他重要查詢不利。其他缺點是具有太多的分區是由於必須將文件系統的所有元數據保留在內存中,因此大量的Hadoop文件和目錄被不必要地創建並且向NameNode開銷。

Bucketing是另一種將數據集分解爲更易管理的部分的技術。例如,假設使用date作爲頂級分區並且employee_id作爲第二級分區的表導致太多的小分區。相反,如果我們存儲員工表並使用employee_id作爲分箱列,則此列的值將由用戶定義的數字散列到存儲桶中。具有相同employee_id的記錄將始終存儲在同一個存儲桶中。假設employee_id的數量遠大於桶的數量,則每個桶將會有很多employee_id。在創建表格時,您可以指定類似CLUSTERED BY (employee_id) INTO XX BUCKETS;,其中XX是存儲桶的數量。 Bucketing具有幾個優點。桶的數量是固定的,因此它不會隨數據波動。如果兩個表被分配employee_id,Hive可以創建一個邏輯上正確的採樣。 Bucketing也有助於做高效的地圖邊連接等。

+2

由於那伏乃爾。但是,您能否詳細說明分區如何發生分叉?假設我們在CLUSED BY子句中指定了32個桶並且CREATE TABLE語句也包含了Partitioning子句,那麼分區和桶將如何一起管理?分區數量是否限制爲32?或者對於每個分區,將創建32個存儲桶?每個存儲桶都是HDFS文件嗎? – sgsi

+9

配置單元表可以同時具有分區和分區。根據您的分區子句,每個分區將創建32個存儲桶。是HDFS文件。 –

+3

@sgsi Partition是一個文件夾,bucket是一個文件。 – leftjoin

15

我想我遲到了回答這個問題,但它一直在我的飼料中出現。

Navneet提供了很好的答案。直觀地添加到它。

如果在WHERE子句中使用分區,分區有助於消除數據,其中分段有助於將每個分區中的數據組織爲多個文件,因此同一組數據總是寫入同一個分區。幫助加入專欄。

假設您有一個包含五列名稱,server_date,some_col3,some_col4和some_col5的表格。假設您已將server_date上的表進行分區,並在名稱列上分區,則您的文件結構如下所示。

  1. server_date = XYZ
    • 00000_0
    • 00001_0
    • 00002_0
    • ........
    • 00010_0

這裏server_date = xyz是分區和文件是每個分區中的存儲桶。存儲桶是根據一些散列函數計算的,所以name = Sandy的行將始終放在同一個存儲桶中。

+0

根據Roberto在上面的回答,server_date將是一個不好的例子,因爲它的**基數**值非常高。所以你最終會在hdfs中擁有太多的文件夾。 –

+0

server_date在此處作爲示例提及。在現實世界中,分區通常按照Roberto描述的方式發生,將日期分爲年/月/日。這是應該的。 – Priyesh

-1

分區:分區基本上是水平的數據片,允許大數據集被分割成更多可管理的數據塊。

CREATE TABLE customer (
id   INT, 
name   STRING, 
address1  STRING)PARTITION BY (REGION STRING,country STRING); 

支持多個「切片器」或分區列(即地區/國家)。

爲分區和在蜂房 鏟裝一個表之間的差值是指this link

13

蜂巢分區:

分區分割數據量大到基於表列值的多個切片(S) 。

假設您正在存儲遍佈全球196個國家的人們的信息,這些信息跨越500多個條目。如果你想查詢來自某個特定國家(梵蒂岡城)的人,在沒有分區的情況下,你必須掃描所有500分錢的條目,甚至可以獲取一個國家的一千個條目。如果您根據國家對錶格進行分區,則可以通過僅檢查一個國家/地區分區的數據來優化查詢過程。 Hive分區爲列(s)值創建單獨的目錄。

優點:

  1. 分發執行負載與數據量少分區的情況下,查詢的水平
  2. 更快的執行。例如從「梵蒂岡城」獲得人口回報非常快,而不是搜索整個世界人口。

缺點:

  1. 太多小分區創作的可能性 - 太多的目錄。
  2. 對於給定分區的低卷數據有效。但是像大量數據一樣的查詢仍然需要很長時間才能執行。例如中國人口分組比梵蒂岡城的人口分組需要很長時間。在數據傾向於特定分區值的情況下,分區不能解決響應問題。

蜂巢桶裝:

桶裝數據分解成更容易管理或相等的部分。

通過分區,您可以根據列值創建多個小分區。如果你選擇bucketing,那麼你正在限制存儲數據的桶的數量。這個數字是在表創建腳本中定義的。

優點

  1. 由於每個分區中的數據的等體積加入在地圖側會更快。像分區
  2. 更快的查詢響應

缺點

  1. 您可以創建表的過程定義桶的數量,但等量數據的加載必須由程序員手動完成。
78

以上解釋中缺少一些細節。 爲了更好地理解分區和分區如何工作,您應該查看數據如何存儲在配置單元中。 比方說,你有一個表中的目錄層次結構

CREATE TABLE mytable ( 
     name string, 
     city string, 
     employee_id int) 
PARTITIONED BY (year STRING, month STRING, day STRING) 
CLUSTERED BY (employee_id) INTO 256 BUCKETS 

然後蜂箱將存儲數據,如

/user/hive/warehouse/mytable/y=2015/m=12/d=02 

所以,你必須要小心,當分區,因爲如果你按employee_id例如分區你有數百萬的員工,你最終會在你的文件系統中擁有數百萬個目錄。 術語'基數'是指字段可能具有的值的數量。例如,如果你有一個「國家」領域,那麼世界上的國家大約有300個,所以基數大約是300。對於像「timestamp_ms」這樣每毫秒發生一次更改的字段,基數可能是數十億。一般來說,當選擇一個字段進行分區時,它不應該有很高的基數,因爲最終會導致文件系統中太多的目錄。

另一方面,聚類aka分組會導致固定數量的文件,因爲您指定了桶的數量。什麼配置單元會做的是採取領域,計算散列並分配一個記錄到該桶。 但是如果你使用的話,會發生什麼呢?比如說256個桶和你正在分配的字段有一個低基數(例如,它是美國的州,所以只能有50個不同的值)?你將有50個數據桶和206個沒有數據的桶。

有人已經提到分區如何顯着減少您查詢的數據量。因此,在我的示例表中,如果您只想從某個特定日期向前查詢,則按年/月/日進行分區將顯着減少IO的數量。 我認爲有人還提到了bucketing可以如何加快與其他表之間的連接,這些表具有完全相同的分組,所以在我的示例中,如果您在同一個employee_id上​​加入兩個表,配置單元可以按桶(如果它們已經按照employee_id排序,那麼它會更好,因爲它將要在線性時間內運行的mergesort)。

因此,當字段具有較高的基數並且數據在桶之間均勻分佈時,bucketing運行良好。當分區字段的基數不太高時,分區效果最好。

此外,可以劃分多個領域,與訂單(年/月/日是一個很好的例子),而你可以鬥上只有一個字段

+0

您能舉一個例子來解釋一下SORTED-BY的CLUSTERED-BY行爲嗎?根據我的例子,我發現SORTED-BY什麼都不做。我錯過了什麼。 –

+1

由x組成,y就像寫x,y分類x,y(見https://cwiki.apache.org/confluence/display/Hive/LanguageManual+SortBy#LanguageManualSortBy-SyntaxofClusterByandDistributeBy),所以添加SORT BY到CLUSTERED BY沒有效果。 –

+0

有趣的是,我同意w.r.t在選擇查詢中的用法。但想知道爲什麼人們在表創建語句中使用聚簇和排序。如果在DDL中對SORTED BY沒有意義,那麼爲什麼這個關鍵字存在?沒有明白。 –

5

所不同的是瓢潑大雨由列名劃分文件,和分區分割文件下由特定值內表

希望我定義它正確