Saya pikir perbedaan utama yang dapat saya jelaskan berkaitan dengan format berorientasi rekaman vs. berorientasi kolom. Format berorientasi rekaman adalah hal yang biasa kita gunakan - file teks, format terbatas seperti CSV, TSV. AVRO sedikit lebih dingin daripada yang bisa mengubah skema dari waktu ke waktu, misalnya menambah atau menghapus kolom dari catatan. Trik lain dari berbagai format (terutama termasuk kompresi) melibatkan apakah suatu format dapat dibagi - yaitu, dapatkah Anda membaca blok catatan dari mana saja dalam dataset dan masih tahu skema itu? Tapi di sini lebih detail tentang format kolom seperti Parket.
Parket, dan format kolom lainnya menangani situasi Hadoop yang umum dengan sangat efisien. Adalah umum untuk memiliki tabel (kumpulan data) yang memiliki lebih banyak kolom daripada yang Anda harapkan dalam database relasional yang dirancang dengan baik - seratus atau dua ratus kolom bukanlah hal yang tidak biasa. Ini karena kita sering menggunakan Hadoop sebagai tempat untuk mendenormalkan data dari format relasional - ya, Anda mendapatkan banyak nilai berulang dan banyak tabel diratakan menjadi satu. Tapi itu menjadi lebih mudah untuk di-query karena semua join dikerjakan. Ada keuntungan lain seperti mempertahankan data negara-dalam-waktu. Jadi bagaimanapun, adalah umum untuk memiliki muatan kolom dalam sebuah tabel.
Katakanlah ada 132 kolom, dan beberapa di antaranya adalah bidang teks yang sangat panjang, masing-masing kolom berbeda satu sama lain dan mungkin menggunakan 10K per catatan.
Meskipun kueri tabel-tabel ini mudah dengan sudut pandang SQL, adalah umum bahwa Anda ingin mendapatkan beberapa catatan berdasarkan hanya beberapa dari beberapa kolom plus-plus itu. Misalnya, Anda mungkin ingin semua catatan pada bulan Februari dan Maret untuk pelanggan dengan penjualan> $ 500.
Untuk melakukan ini dalam format baris, kueri perlu memindai setiap catatan dataset. Baca baris pertama, parsing catatan ke dalam bidang (kolom) dan dapatkan kolom tanggal dan penjualan, sertakan di hasil Anda jika memenuhi kondisi. Ulang. Jika Anda memiliki 10 tahun (120 bulan) sejarah, Anda membaca setiap catatan hanya untuk menemukan 2 dari bulan-bulan itu. Tentu saja ini adalah kesempatan bagus untuk menggunakan partisi pada tahun dan bulan, tetapi meskipun demikian, Anda membaca dan menguraikan 10K dari setiap record / baris selama dua bulan hanya untuk menemukan apakah penjualan pelanggan> $ 500.
Dalam format kolom, setiap kolom (bidang) dari catatan disimpan dengan yang lain dari jenisnya, tersebar di banyak blok berbeda pada disk - kolom untuk tahun bersama, kolom untuk bulan bersama, kolom untuk buku pegangan karyawan karyawan (atau lainnya teks panjang), dan semua yang membuat catatan itu begitu besar di tempat mereka masing-masing pada disk, dan tentu saja kolom untuk penjualan bersama. Nah, tanggal dan bulan adalah angka, dan begitu juga penjualan - mereka hanya beberapa byte. Bukankah lebih bagus jika kita hanya perlu membaca beberapa byte untuk setiap catatan untuk menentukan catatan mana yang cocok dengan kueri kita? Penyimpanan kolom untuk menyelamatkan!
Bahkan tanpa partisi, pemindaian bidang kecil yang diperlukan untuk memenuhi permintaan kami sangat cepat - semuanya terurut berdasarkan catatan, dan semuanya berukuran sama, sehingga disk mencari lebih sedikit data untuk memeriksa catatan yang disertakan. Tidak perlu membaca buku pegangan karyawan dan bidang teks panjang lainnya - abaikan saja. Jadi, dengan mengelompokkan kolom satu sama lain, alih-alih baris, Anda hampir selalu dapat memindai lebih sedikit data. Menang!
Tapi tunggu, ini jadi lebih baik. Jika kueri Anda hanya perlu mengetahui nilai-nilai itu dan beberapa lagi (misalkan 10 dari 132 kolom) dan tidak peduli dengan kolom buku pegangan karyawan itu, setelah ia mengambil catatan yang tepat untuk dikembalikan, sekarang hanya tinggal pergi kembali ke 10 kolom yang diperlukan untuk memberikan hasil, mengabaikan 122 lainnya dari 132 dalam dataset kami. Sekali lagi, kami melewatkan banyak membaca.
(Catatan: karena alasan ini, format kolom adalah pilihan yang buruk ketika melakukan transformasi langsung, misalnya, jika Anda menggabungkan semua dua tabel menjadi satu (ger) hasil besar yang Anda simpan sebagai tabel baru, sumbernya akan dipindai sepenuhnya, jadi tidak ada banyak manfaat dalam kinerja membaca, dan karena format kolom perlu mengingat lebih banyak tentang di mana barang-barang berada, mereka menggunakan lebih banyak memori daripada format baris yang sama).
Satu lagi manfaat kolom: data tersebar di mana-mana. Untuk mendapatkan satu catatan, Anda dapat meminta masing-masing 132 pekerja membaca (dan menulis) data dari / ke 132 tempat berbeda di 132 blok data. Yay untuk paralelisasi!
Dan sekarang untuk penentu: algoritma kompresi bekerja jauh lebih baik ketika dapat menemukan pola berulang. Anda bisa kompres AABBBBBBCCCCCCCCCCCCCCCC
sebagai 2A6B16C
tetapi ABCABCBCBCBCCCCCCCCCCCCCC
tidak akan mendapatkan kecil (baik, sebenarnya, dalam hal ini akan, tapi percayalah :-)). Jadi sekali lagi, kurang membaca. Dan menulis juga.
Jadi kami membaca lebih sedikit data untuk menjawab pertanyaan umum, ini berpotensi lebih cepat untuk membaca dan menulis secara paralel, dan kompresi cenderung bekerja lebih baik.
Kolom bagus ketika sisi input Anda besar, dan output Anda adalah subset yang difilter: dari besar ke kecil adalah besar. Tidak menguntungkan ketika input dan output hampir sama.
Tetapi dalam kasus kami, Impala mengambil pertanyaan Hive lama kami yang berjalan dalam 5, 10, 20 atau 30 menit, dan menyelesaikan sebagian besar dalam beberapa detik atau satu menit.
Semoga ini bisa membantu menjawab setidaknya sebagian dari pertanyaan Anda!