Jawaban:
Partisi data sering digunakan untuk mendistribusikan beban secara horizontal, ini memiliki manfaat kinerja, dan membantu dalam mengatur data secara logis. Contoh : jika kita berhadapan dengan employee
tabel besar dan sering menjalankan kueri dengan WHERE
klausa yang membatasi hasil untuk negara atau departemen tertentu. Untuk respons kueri yang lebih cepat, tabel Hive dapat dibuat PARTITIONED BY (country STRING, DEPT STRING)
. Tabel partisi mengubah bagaimana Hive struktur penyimpanan data dan Hive sekarang akan membuat subdirektori yang mencerminkan struktur partisi seperti
... / karyawan / negara = ABC / DEPT = XYZ .
Jika batasan kueri untuk karyawan dari country=ABC
, itu hanya akan memindai konten dari satu direktori country=ABC
. Ini secara dramatis dapat meningkatkan kinerja kueri, tetapi hanya jika skema partisi mencerminkan pemfilteran umum. Fitur pemartisian sangat berguna di Hive, namun, desain yang membuat terlalu banyak partisi dapat mengoptimalkan beberapa kueri, tetapi akan mengganggu kueri penting lainnya. Kelemahan lainnya adalah terlalu banyak partisi adalah banyaknya file dan direktori Hadoop yang dibuat tidak perlu dan overhead ke NameNode karena harus menyimpan semua metadata untuk sistem file dalam memori.
Bucketing adalah teknik lain untuk mendekomposisi set data menjadi bagian yang lebih mudah dikelola. Sebagai contoh, anggaplah sebuah tabel menggunakan date
sebagai partisi tingkat atas dan employee_id
sebagai partisi tingkat kedua menyebabkan terlalu banyak partisi kecil. Alih-alih, jika kita mengaitkan tabel karyawan dan digunakan employee_id
sebagai kolom penimbunan, nilai kolom ini akan di-hash dengan angka yang ditentukan pengguna menjadi ember. Catatan dengan hal yang sama employee_id
akan selalu disimpan dalam ember yang sama. Dengan asumsi jumlah employee_id
jauh lebih besar daripada jumlah ember, setiap ember akan memiliki banyak employee_id
. Saat membuat tabel Anda dapat menentukan sukaCLUSTERED BY (employee_id) INTO XX BUCKETS;
di mana XX adalah jumlah ember. Bucketing memiliki beberapa keunggulan. Jumlah bucket diperbaiki sehingga tidak berfluktuasi dengan data. Jika dua tabel diatasi oleh employee_id
, Hive dapat membuat pengambilan sampel yang benar secara logis. Memberi ember juga membantu dalam melakukan penggabungan sisi-peta yang efisien, dll.
Ada beberapa detail yang hilang dari penjelasan sebelumnya. Untuk lebih memahami cara kerja partisi dan bucket, Anda harus melihat bagaimana data disimpan di sarang. Katakanlah Anda punya meja
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
maka sarang akan menyimpan data dalam hirarki direktori seperti
/user/hive/warehouse/mytable/y=2015/m=12/d=02
Jadi, Anda harus berhati-hati ketika mempartisi, karena jika Anda misalnya mempartisi oleh employee_id dan Anda memiliki jutaan karyawan, Anda akan memiliki jutaan direktori di sistem file Anda. Istilah ' kardinalitas ' mengacu pada jumlah nilai yang mungkin dimiliki suatu bidang. Misalnya, jika Anda memiliki bidang 'negara', negara-negara di dunia adalah sekitar 300, jadi kardinalitas akan ~ 300. Untuk bidang seperti 'timestamp_ms', yang berubah setiap milidetik, kardinalitas bisa miliaran. Secara umum, ketika memilih bidang untuk dipartisi, seharusnya tidak memiliki kardinalitas tinggi, karena Anda akan berakhir dengan direktori terlalu banyak dalam sistem file Anda.
Clustering alias bucketing di sisi lain, akan menghasilkan jumlah file yang tetap, karena Anda menentukan jumlah bucket. Apa sarang akan lakukan adalah untuk mengambil bidang, menghitung hash dan menetapkan catatan ke ember itu. Tetapi apa yang terjadi jika Anda menggunakan katakanlah 256 ember dan bidang yang Anda tangani memiliki kardinalitas rendah (misalnya, ini adalah negara bagian AS, jadi hanya 50 nilai yang berbeda)? Anda akan memiliki 50 ember dengan data, dan 206 ember tanpa data.
Seseorang telah menyebutkan bagaimana partisi dapat secara dramatis memotong jumlah data yang Anda tanyakan. Jadi, dalam tabel contoh saya, jika Anda ingin melakukan kueri hanya dari tanggal tertentu ke depan, partisi berdasarkan tahun / bulan / hari akan secara dramatis memotong jumlah IO. Saya pikir seseorang juga menyebutkan bagaimana bucket dapat mempercepat penggabungan dengan tabel lain yang memiliki bucket yang sama persis , jadi dalam contoh saya, jika Anda bergabung dengan dua tabel pada employee_id yang sama, sarang dapat melakukan gabungan bucket dengan bucket (bahkan lebih baik jika mereka sudah diurutkan berdasarkan employee_id karena akan menggabungkan bagian-bagian yang sudah diurutkan, yang bekerja dalam waktu linier alias O (n)).
Jadi, bucket bekerja dengan baik ketika bidang memiliki kardinalitas tinggi dan data didistribusikan secara merata di antara bucket. Partisi berfungsi paling baik ketika kardinalitas bidang partisi tidak terlalu tinggi.
Selain itu, Anda dapat mempartisi pada beberapa bidang , dengan pesanan (tahun / bulan / hari adalah contoh yang baik), sementara Anda hanya dapat melakukan bucket pada satu bidang .
Saya pikir saya terlambat menjawab pertanyaan ini, tetapi terus muncul di feed saya.
Navneet telah memberikan jawaban yang sangat bagus. Menambahkannya secara visual.
Partisi membantu dalam penghapusan data, jika digunakan dalam klausa WHERE, sedangkan bucket membantu dalam mengatur data di setiap partisi menjadi beberapa file, sehingga kumpulan data yang sama selalu ditulis dalam ember yang sama. Banyak membantu dalam menggabungkan kolom.
Misalkan, Anda memiliki tabel dengan lima kolom, nama, server_date, some_col3, some_col4 dan some_col5. Misalkan, Anda telah mempartisi tabel pada server_date dan di- bucket pada kolom nama dalam 10 ember, struktur file Anda akan terlihat seperti di bawah ini.
Di sini server_date = xyz adalah partisi dan 000 file adalah ember di setiap partisi. Bucket dihitung berdasarkan beberapa fungsi hash, jadi baris dengan nama = Sandy akan selalu masuk dalam bucket yang sama.
Sarang Partisi:
Partisi membagi sejumlah besar data menjadi beberapa irisan berdasarkan nilai kolom tabel.
Asumsikan bahwa Anda menyimpan informasi orang-orang di seluruh dunia yang tersebar di 196+ negara yang mencakup sekitar 500 crores entri. Jika Anda ingin meminta orang dari negara tertentu (kota Vatikan), jika tidak ada partisi, Anda harus memindai semua 500 crores entri bahkan untuk mengambil ribuan entri dari suatu negara. Jika Anda mempartisi tabel berdasarkan negara, Anda dapat mengatur proses kueri hanya dengan memeriksa data hanya satu partisi negara. Partisi sarang membuat direktori terpisah untuk nilai kolom.
Pro:
Cons:
Sarang Bucketing:
Bucket menguraikan data menjadi bagian yang lebih mudah dikelola atau sama.
Dengan mempartisi, ada kemungkinan Anda bisa membuat banyak partisi kecil berdasarkan nilai kolom. Jika Anda menggunakan bucket, Anda membatasi jumlah bucket untuk menyimpan data. Angka ini didefinisikan selama skrip pembuatan tabel.
Pro
Cons
Sebelum masuk Bucketing
, kita perlu memahami apa Partitioning
itu. Mari kita ambil tabel di bawah ini sebagai contoh. Perhatikan bahwa saya hanya memberikan 12 catatan dalam contoh di bawah ini untuk pemahaman tingkat pemula. Dalam skenario real-time Anda mungkin memiliki jutaan catatan.
PARTITIONING
---------------------
Partitioning
digunakan untuk mendapatkan kinerja saat meminta data. Misalnya, dalam tabel di atas, jika kita menulis sql di bawah ini, perlu memindai semua catatan di tabel yang mengurangi kinerja dan meningkatkan overhead.
select * from sales_table where product_id='P1'
Untuk menghindari pemindaian tabel penuh dan hanya membaca catatan yang terkait dengan product_id='P1'
kita dapat mempartisi (membagi file tabel sarang) menjadi beberapa file berdasarkan product_id
kolom. Dengan ini file tabel sarang akan dibagi menjadi dua file satu dengan product_id='P1'
dan lainnya dengan product_id='P2'
. Sekarang ketika kita menjalankan query di atas, itu hanya akan memindai product_id='P1'
file.
../hive/warehouse/sales_table/product_id=P1
../hive/warehouse/sales_table/product_id=P2
Sintaks untuk membuat partisi diberikan di bawah ini. Perhatikan bahwa kita tidak boleh menggunakan product_id
definisi kolom bersama dengan kolom yang tidak dipartisi dalam sintaksis di bawah ini. Ini seharusnya hanya dalam partitioned by
klausa.
create table sales_table(sales_id int,trans_date date, amount int)
partitioned by (product_id varchar(10))
Cons : Kita harus sangat berhati-hati saat mempartisi. Artinya, itu tidak boleh digunakan untuk kolom di mana jumlah nilai berulang sangat kurang (terutama kolom kunci utama) karena meningkatkan jumlah file yang dipartisi dan meningkatkan overhead untuk Name node
.
BUCKETING
------------------
Bucketing
digunakan untuk mengatasi cons
yang saya sebutkan di bagian partisi. Ini harus digunakan ketika ada sangat sedikit nilai yang berulang dalam kolom (contoh - kolom kunci utama). Ini mirip dengan konsep indeks pada kolom kunci utama dalam RDBMS. Di meja kami, kami dapat mengambil Sales_Id
kolom untuk disemen. Ini akan berguna ketika kita perlu menanyakan sales_id
kolom.
Di bawah ini adalah sintaksis untuk bucket.
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
Di sini kita akan membagi data menjadi beberapa file di atas partisi.
Karena kami telah menentukan 3
bucket, masing-masing dibagi menjadi 3 file untuk masing-masing product_id
. Ini digunakan secara internal modulo operator
untuk menentukan di mana masing sales_id
- masing ember harus disimpan. Misalnya, untuk product_id='P1'
, sales_id=1
akan disimpan dalam file 000001_0 (yaitu, 1% 3 = 1), sales_id=2
akan disimpan dalam file 000002_0 (yaitu, 2% 3 = 2), sales_id=3
akan disimpan dalam file 000000_0 (yaitu, 3% 3 = 0) dll.
hashCode()
dari string sebagai fungsi hash? Bisakah programmer memilih fungsi hash?
Perbedaannya adalah membagi ember file dengan Nama Kolom, dan partisi membagi file di bawah Dengan nilai tertentu di dalam tabel
Semoga saya mendefinisikannya dengan benar
Ada banyak tanggapan di sini. Saya ingin membuatnya singkat untuk menghafal perbedaan antara partisi & bucket.
Anda biasanya mempartisi pada kolom yang kurang unik. Dan ember pada kolom paling unik.
Contoh jika Anda menganggap populasi Dunia dengan negara, nama orang, dan id bio-metrik mereka sebagai contoh. Seperti yang bisa Anda tebak, bidang negara akan menjadi kolom yang kurang unik dan bio-metrik id akan menjadi kolom yang paling unik. Jadi idealnya Anda perlu mempartisi tabel berdasarkan negara dan mengisinya dengan bio-metric id.
Menggunakan Partisi dalam tabel Hive sangat disarankan karena alasan di bawah ini -
Contoh: -
Asumsikan bahwa File Input (100 GB) dimuat ke dalam tabel temp-hive dan berisi data bank dari berbagai wilayah.
Sarang meja tanpa Partisi
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
Masalah dengan pendekatan ini adalah - Ini akan memindai seluruh data untuk setiap kueri yang Anda jalankan di tabel ini. Waktu respons akan tinggi dibandingkan dengan pendekatan lain di mana partisi dan Bucketing digunakan.
Sarang meja dengan Partisi
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)
Kelebihan - Di sini orang dapat mengakses data lebih cepat ketika datang ke permintaan data untuk transaksi geografi tertentu. Kontra - Memasukkan / meminta data lebih lanjut dapat ditingkatkan dengan memisahkan data di dalam setiap partisi. Lihat opsi Bucketing di bawah ini.
Sarang meja dengan Partisi dan Bucketing
Catatan: Buat tabel sarang ..... dengan "CLUSTERED BY (Partiton_Column) menjadi 5 ember
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)
Pro - Sisipan Lebih Cepat. Permintaan Lebih Cepat.
Kontra - Bucketing akan membuat lebih banyak file. Mungkin ada masalah dengan banyak file kecil dalam beberapa kasus tertentu
Semoga ini bisa membantu !!