Hive'da bir tabloyu bölümleme ile gruplama arasındaki fark nedir?


130

Her ikisinin de tablodaki bir sütunda yapıldığını biliyorum, ancak her işlem nasıl farklıdır.

Yanıtlar:


247

Veri bölümleme verileri genellikle yükü yatay olarak dağıtmak için kullanılır, bunun performans avantajı vardır ve verileri mantıksal bir şekilde organize etmeye yardımcı olur. Örnek : Büyük bir employeetabloyla uğraşıyorsak WHEREve sonuçları belirli bir ülke veya departmanla sınırlayan cümlelere sahip sorgular çalıştırıyorsak . Daha hızlı bir sorgu yanıtı için Hive tablosu olabilir PARTITIONED BY (country STRING, DEPT STRING). Bölümleme tabloları, Hive'ın veri depolamayı yapılandırma şeklini değiştirir ve Hive artık bölümleme yapısını yansıtan alt dizinler oluşturacaktır.

... / çalışanlar / ülke = ABC / DEPT = XYZ .

Çalışan için sorgu sınırı varsa country=ABC, yalnızca bir dizinin içeriğini tarayacaktır country=ABC. Bu, sorgu performansını önemli ölçüde artırabilir, ancak yalnızca bölümleme şeması ortak filtrelemeyi yansıtıyorsa. Bölümleme özelliği Hive'da çok kullanışlıdır, ancak çok fazla bölüm oluşturan bir tasarım bazı sorguları optimize edebilir, ancak diğer önemli sorgular için zararlı olabilir. Diğer bir dezavantaj, çok fazla bölüme sahip olmanın, gereksiz yere oluşturulan çok sayıda Hadoop dosyası ve dizinidir ve dosya sistemi için tüm meta verileri bellekte tutması gerektiğinden NameNode'a ek yük getirir.

Paketleme , veri setlerini daha yönetilebilir parçalara ayırmak için başka bir tekniktir. Örneğin date, üst düzey bölüm employee_idolarak ve ikinci düzey bölüm olarak kullanılan bir tablonun çok fazla küçük bölüme yol açtığını varsayın . Bunun yerine, çalışan tablosunu employee_idgruplandırırsak ve gruplama sütunu olarak kullanırsak , bu sütunun değeri, kullanıcı tanımlı bir sayı ile paketler halinde hashing uygulanacaktır. Aynı olan employee_id kayıtlar her zaman aynı pakette saklanacaktır. Sayısının, employee_idkova sayısından çok daha fazla olduğu varsayılırsa , her bir kova çok sayıda olacaktır employee_id. Tablo oluştururken aşağıdaki gibi belirtebilirsinizCLUSTERED BY (employee_id) INTO XX BUCKETS;XX, paketlerin sayısıdır. Paketlemenin çeşitli avantajları vardır. Veri grubu sayısı sabittir, böylece verilerle dalgalanma olmaz. İki tablo tarafından gruplandırılırsa employee_id, Hive mantıksal olarak doğru bir örnekleme oluşturabilir. Paketleme aynı zamanda verimli harita tarafı birleştirmeler vb.


4
Teşekkürler Navneet. Bununla birlikte, bölümlemeyle gruplamanın nasıl gerçekleştiğini detaylandırabilir misiniz? Diyelim ki CLUSED BY yan tümcesinde 32 kova belirtirsek ve CREATE TABLE deyimi de Partitioning yan tümcesini içeriyorsa, bölümler ve kümeler birlikte nasıl yönetilecek? Bölüm sayısı 32 ile mi sınırlı olacak? VEYA her bölüm için 32 kova oluşturulacak mı? Her kova bir HDFS dosyası mı?
sgsi

12
Bir kovan tablosu hem bölümlere hem de gruplamaya sahip olabilir. Bölüm hükmünüze göre, her bölüm için oluşturulan 32 kova olacaktır. Evet HDFS dosyası.
Navneet Kumar

7
@sgsi Partition bir klasör, kova bir dosyadır.
2016

12
Kayıt için, bu cevap Programming Hive (O'Reilly, 2012) metninden geliyor .
ianmcook

1
Bu bağlantıyı faydalı buldum. Bu cevaba daha fazla değer katacak bilgiler içermektedir. linkedin.com/pulse/…
Alex Raj Kaliamoorthy

129

Önceki açıklamalarda eksik olan birkaç ayrıntı var. Bölümleme ve gruplamanın nasıl çalıştığını daha iyi anlamak için verilerin kovanda nasıl depolandığına bakmalısınız. Diyelim ki bir masanız var

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

daha sonra kovan, verileri aşağıdaki gibi bir dizin hiyerarşisinde depolar

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

Bu nedenle, bölümleme sırasında dikkatli olmalısınız, çünkü örneğin, worker_id ile bölümleme yaparsanız ve milyonlarca çalışanınız varsa, dosya sisteminizde milyonlarca dizine sahip olursunuz. ' Asıllık ' terimi, bir alanın sahip olabileceği olası değer sayısını ifade eder. Örneğin, bir 'ülke' alanınız varsa, dünyadaki ülkeler yaklaşık 300, yani kardinalite ~ 300 olacaktır. Her milisaniyede değişen 'timestamp_ms' gibi bir alan için kardinalite milyarlarca olabilir. Genel olarak, bölümleme için bir alan seçerken, yüksek bir kardinalitesi olmamalıdır, çünkü dosya sisteminizde çok fazla dizinle karşılaşacaksınız.

Öte yandan kümeleme, paket sayısını belirttiğiniz için sabit sayıda dosyayla sonuçlanır. Kovanın yapacağı şey, tarlayı almak, bir hash hesaplamak ve bu kovaya bir kayıt atamaktır. Ama diyelim ki 256 kova kullanırsanız ve üzerinde topladığınız alanın düşük bir kardinalitesi varsa (örneğin, bu bir ABD eyaleti, bu nedenle sadece 50 farklı değer olabilir) ne olur? Veri içeren 50 paketiniz ve veri içermeyen 206 paketiniz olacak.

Birisi, bölümlerin sorguladığınız veri miktarını nasıl önemli ölçüde azaltabileceğinden bahsetti. Yani benim örnek tablomda, yalnızca belirli bir tarihten itibaren sorgu yapmak istiyorsanız, yıl / ay / güne göre bölümleme, GÇ miktarını önemli ölçüde azaltacaktır. Sanırım birisinin, paketlemenin tam olarak aynı gruplamaya sahip diğer masalarla birleşimleri nasıl hızlandırabileceğinden de bahsettiğini düşünüyorum , bu nedenle benim örneğimde , aynı staff_id üzerinde iki masayı birleştiriyorsanız, kovan birleştirme kovasını kovayla yapabilir (daha da iyisi zaten sıralanan parçaları birleştireceğinden, bu, doğrusal zamanda yani O (n)) çalıştığı için zaten staff_id'ye göre sıralılarsa.

Bu nedenle, alan yüksek kardinaliteye sahip olduğunda ve veriler kovalar arasında eşit olarak dağıtıldığında gruplama iyi çalışır. Bölümleme, bölümleme alanının önem düzeyi çok yüksek olmadığında en iyi şekilde çalışır.

Ayrıca, bir siparişle (yıl / ay / gün iyi bir örnektir) birden çok alana bölümleme yapabilirken, yalnızca tek bir alanda bölümleme yapabilirsiniz .


SIRALANDIRILAN ile KÜMELENME davranışını bir örnekle açıklayabilir misiniz? Örneğime göre SORTED-BY'ı hiçbir şey yapmadan buldum. Bir şey kaçırıyor muyum?
Jagadish Talluri

2
KÜMELENMİŞ x, y, x'E GÖRE DAĞITIM, y SIRALAMA x, y yazmak gibidir (bkz. Cwiki.apache.org/confluence/display/Hive/… ), bu nedenle KÜMELENEN'e SIRALAMA'nın eklenmesinin bir etkisi yoktur.
Roberto Congiu

İlginç, seçim sorgusunda kullanımı kabul ediyorum. Ancak insanların neden tablo oluşturma deyiminde kümelenmiş ve birlikte sıralı olarak kullandıklarını merak ettik. DDL'de SIRALANDIRILAN'ın önemi yoksa, bu anahtar kelime neden var? Anlamadım.
Jagadish Talluri

SIRALANDIRMA TARAFINDAN DISTRIBUTED BY ile kullanılmak içindir. Örneğin, kullanıcı kimliğine göre dağıtmak ve paket içinde zamana göre sıralamak isteyebilirsiniz. CLUSTER BY, SORTED BY ve DISTRIBUTED BY'daki cümleciklerin aynı olduğu durumlar için bir kısayoldur. Aklıma gelen tek şey, x, y'ye göre dağıtım yapıyorsanız ve x, y ve z'ye göre sıralamanızdır
Roberto Congiu

"Sadece bir tarlaya gidebilirsin" derken neyi kastettiğinden emin değilim. Birden fazla alana göre gruplamanın mümkün olduğunu düşünüyorum, karma işlevi yalnızca tüm alanları alıp bunları birleştirecektir.
Istvan

18

Sanırım bu soruyu cevaplamakta geç kaldım, ama bu sürekli olarak akışımda görünmeye devam ediyor.

Navneet mükemmel yanıt verdi. Görsel olarak eklemek.

Bölümleme, WHERE yan tümcesinde kullanılıyorsa verilerin ortadan kaldırılmasına yardımcı olur; burada paketleme, her bölümdeki verilerin birden çok dosyaya düzenlenmesine yardımcı olur, böylece aynı veri kümesi her zaman aynı pakete yazılır. Sütunların birleşmesine çok yardımcı olur.

Beş sütunlu bir tablonuz olduğunu varsayalım: name, server_date, some_col3, some_col4 ve some_col5. Diyelim ki, server_date üzerindeki tabloyu bölümlendirdiniz ve 10 kova halinde isim sütununda gruplandınız, dosya yapınız aşağıdaki gibi görünecek.

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

Burada server_date = xyz bölümdür ve 000 dosya her bölümdeki kovalardır. Paketler bazı hash işlevlerine göre hesaplanır, bu nedenle name = Sandy olan satırlar her zaman aynı pakete gider.


2
Yukarıdaki cevapta Roberto'ya göre server_date, kardinalite değeri gerçekten yüksek olduğu için bölümleme yapmak için kötü bir örnek olabilir . Ve böylece hdflerde çok fazla klasörünüz olacak.
Gaurang Shah

server_date burada örnek olarak belirtilmiştir. Gerçek dünyada, bölüm genellikle Roberto tarafından gösterildiği gibi tarihi yıl / ay / güne bölerek gerçekleşir. Böyle olması gerekiyor.
Priyesh

17

Kovan Bölümleme:

Bölüm, büyük miktarda veriyi bir tablo sütun (lar) ının değerine göre birden çok dilime böler.

Yaklaşık 500 girişten oluşan 196'dan fazla ülkeye yayılmış tüm dünyadaki insanların bilgilerini depoladığınızı varsayalım. Belirli bir ülkeden (Vatikan şehri) insanları sorgulamak istiyorsanız, bölümlemenin yokluğunda, bir ülkenin bin girişini almak için bile 500 girişin tümünü taramanız gerekir. Tabloyu ülkeye göre bölümlendirirseniz, yalnızca bir ülke bölümü için verileri kontrol ederek sorgulama sürecine ince ayar yapabilirsiniz. Kovan bölümü, sütun (lar) değeri için ayrı bir dizin oluşturur.

Artıları:

  1. Yürütme yükünü yatay olarak dağıtın
  2. Düşük veri hacimli bölümleme durumunda sorguların daha hızlı yürütülmesi. Örneğin " Vatikan Şehri " nden nüfusu alın dünya nüfusunun tamamını aramak yerine çok hızlı geri döner.

Eksileri:

  1. Çok fazla sayıda küçük bölüm oluşturma olasılığı - çok fazla dizin.
  2. Belirli bir bölüm için düşük hacimli veriler için etkilidir. Ancak, yüksek miktarda veri üzerinde gruplama gibi bazı sorguların yürütülmesi hala uzun zaman alıyor. Örneğin, Çin nüfusunun gruplanması, Vatikan kentindeki nüfusun gruplandırılmasına kıyasla uzun zaman alacaktır. Verilerin belirli bir bölüm değerine doğru eğilmesi durumunda bölümleme yanıt verme sorununu çözmüyor.

Kovan Kovalama:

Paketleme, verileri daha yönetilebilir veya eşit parçalara ayırır.

Bölümleme ile, sütun değerlerine göre birden çok küçük bölüm oluşturma olasılığı vardır. Paketlemeye giderseniz, verileri depolamak için paket sayısını sınırlamış olursunuz. Bu sayı, tablo oluşturma komut dosyaları sırasında tanımlanır.

Artıları

  1. Her bölümdeki eşit miktarda veri nedeniyle, Harita tarafındaki birleşimler daha hızlı olacaktır.
  2. Bölümleme gibi daha hızlı sorgu yanıtı

Eksileri

  1. Tablo oluşturma sırasında grup sayısını tanımlayabilirsiniz, ancak eşit hacimde verilerin yüklenmesi programcılar tarafından manuel olarak yapılmalıdır.

9

İçeri girmeden önce Bucketing, ne Partitioningolduğunu anlamamız gerekiyor . Aşağıdaki tabloyu örnek olarak alalım. Aşağıdaki örnekte başlangıç ​​seviyesinde anlayış için sadece 12 kayıt verdiğimi unutmayın. Gerçek zamanlı senaryolarda milyonlarca kayda sahip olabilirsiniz.

görüntü açıklamasını buraya girin



PARTITIONING
---------------------
Partitioning , verileri sorgularken performans elde etmek için kullanılır. Örneğin yukarıdaki tabloya aşağıdaki sql yazacak olursak tablodaki tüm kayıtları taraması gerekir ki bu da performansı düşürür ve yükü arttırır.

select * from sales_table where product_id='P1'

Tam tablo taramasından kaçınmak ve yalnızca ilgili kayıtları okumak için product_id='P1', product_idsütuna göre birden çok dosyaya bölümleyebiliriz (kovan tablosunun dosyalarını bölebiliriz) . Bununla, kovan tablosunun dosyası, biri ile product_id='P1'diğeri ile iki dosyaya bölünecektir product_id='P2'. Şimdi yukarıdaki sorguyu çalıştırdığımızda sadece product_id='P1'dosyayı tarayacak .

../hive/warehouse/sales_table/product_id=P1
../hive/warehouse/sales_table/product_id=P2

Bölümü oluşturmak için sözdizimi aşağıda verilmiştir. product_idAşağıdaki söz diziminde sütun tanımını bölümlenmemiş sütunlarla birlikte kullanmamamız gerektiğini unutmayın . Bu sadece partitioned bymaddede olmalıdır.

create table sales_table(sales_id int,trans_date date, amount int) 
partitioned by (product_id varchar(10))

Eksileri : Bölünürken çok dikkatli olmalıyız. Yani, bölümlenmiş dosyaların sayısını artırdığı ve Name node.



BUCKETING
------------------ bölümleme bölümünde bahsettiğim şeyin
Bucketingüstesinden gelmek için kullanılır cons. Bu, bir sütunda çok az sayıda yinelenen değer olduğunda kullanılmalıdır (örnek - birincil anahtar sütunu). Bu, RDBMS'deki birincil anahtar sütunundaki dizin kavramına benzer. Tabloda, kova için Sales_Idsütun alabiliriz . sales_idSütunu sorgulamamız gerektiğinde faydalı olacaktır .

Paketleme için sözdizimi aşağıdadır.

create table sales_table(sales_id int,trans_date date, amount int) 
partitioned by (product_id varchar(10)) Clustered by(Sales_Id) into 3 buckets

Burada verileri bölümlerin üstünde birkaç dosyaya daha da böleceğiz.

görüntü açıklamasını buraya girin

3Grupları belirttiğimizden , her biri için 3 dosyaya bölünmüştür product_id. Her modulo operatorbirinin hangi kovada sales_iddepolanması gerektiğini belirlemek için dahili olarak kullanır . Örneğin, için product_id='P1', sales_id=1depolanacak 000001_0 (örneğin,% 1 3 = 1), dosyaya sales_id=2kaydedilir 000002_0 (yani, 2% 3 = 2), dosyaya sales_id=3kaydedilir 000000_0 dosyası (örneğin,% 3 3 = 0) vb.


Sayısal kümelenmiş sütunlar için, her zaman yalnızca kova sayısına göre mod alır mı? Dize değerli kümelenmiş sütunlar için, hashCode()karma işlevi olarak dizenin Java'sını kullanıyor mu? Programcı hash fonksiyonunu seçebilir mi?
Don Smith

Görünüşe göre (ve deneylerime göre) kovan, Java'nın hashCode () yönteminin bir varyasyonunu kullanıyor: github.com/apache/hive/blob/release-1.1.0/serde/src/java/org/… . Bundan burada bahsedilmiştir: stackoverflow.com/questions/30594038/… .
Don Smith

3

Aradaki fark, paketlemenin dosyaları Sütun Adına ve bölümlemenin altındaki dosyaları tablonun içindeki belirli bir değere göre böler.

Umarım doğru tanımladım


0

Burada harika yanıtlar var. Bölme ve kovalar arasındaki farkı ezberlemek için kısa tutmak istiyorum.

Genellikle daha az benzersiz bir sütunda bölümlersiniz. Ve en benzersiz sütunda kümeleme.

Örnek olarak ülke, kişi adı ve biyo-metrik kimliği ile birlikte Dünya nüfusunu düşünürseniz. Tahmin edebileceğiniz gibi, ülke alanı daha az benzersiz olan sütun ve biyo-metrik kimliği en benzersiz sütun olacaktır. Dolayısıyla ideal olarak tabloyu ülkeye göre bölümlere ayırmanız ve onu biyo-metrik kimliğe göre gruplamanız gerekir.


-1

Kovan tablosunda Bölümlerin kullanılması aşağıdaki nedenlerden dolayı şiddetle tavsiye edilir -

  • Hive tablosuna ekleme daha hızlı olmalıdır (bölümlere veri yazmak için birden çok iş parçacığı kullandığından)
  • Hive tablosundan gelen sorgu, düşük gecikme süresiyle verimli olmalıdır.

Misal :-

Girdi Dosyasının (100 GB) geçici kovan tablosuna yüklendiğini ve farklı coğrafyalardan banka verilerini içerdiğini varsayalım.

Bölmesiz kovan tablosu

Insert into Hive table Select * from temp-hive-table

/hive-table-path/part-00000-1  (part size ~ hdfs block size)
/hive-table-path/part-00000-2
....
/hive-table-path/part-00000-n

Bu yaklaşımla ilgili sorun - Bu tabloda çalıştırdığınız herhangi bir sorgu için tüm verileri tarayacaktır. Tepki süresi, bölümleme ve Gruplamanın kullanıldığı diğer yaklaşımlarla karşılaştırıldığında yüksek olacaktır.

Bölmeli kovan tablosu

Insert into Hive table partition(country) Select * from temp-hive-table

/hive-table-path/country=US/part-00000-1       (file size ~ 10 GB)
/hive-table-path/country=Canada/part-00000-2   (file size ~ 20 GB)
....
/hive-table-path/country=UK/part-00000-n       (file size ~ 5 GB)

Artıları - Burada, belirli coğrafya işlemleri için veri sorgulama söz konusu olduğunda verilere daha hızlı erişebilirsiniz. Eksileri - Veri ekleme / sorgulama, her bölümdeki verileri bölerek daha da geliştirilebilir. Aşağıdaki Paketleme seçeneğine bakın.

Bölme ve Paketleme ile kovan tablosu

Not: "CLUSTERED BY (Partiton_Column) ile 5 paket halinde ..... kovan tablosu oluşturun

Insert into Hive table partition(country) Select * from temp-hive-table

/hive-table-path/country=US/part-00000-1       (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-2       (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-3       (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-4       (file size ~ 2 GB)
/hive-table-path/country=US/part-00000-5       (file size ~ 2 GB)

/hive-table-path/country=Canada/part-00000-1   (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-2   (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-3   (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-4   (file size ~ 4 GB)
/hive-table-path/country=Canada/part-00000-5   (file size ~ 4 GB)

....
/hive-table-path/country=UK/part-00000-1       (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-2       (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-3       (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-4       (file size ~ 1 GB)
/hive-table-path/country=UK/part-00000-5       (file size ~ 1 GB)

Artıları - Daha Hızlı Ekleme. Daha Hızlı Sorgu.

Eksileri - Paketleme daha fazla dosya oluşturacaktır. Bazı özel durumlarda birçok küçük dosyada sorun olabilir.

Umarım bu yardımcı olur !!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.