HBase
 sql >> Teknologi Basis Data >  >> NoSQL >> HBase

HBase BlockCache 101

Pos blog ini dipublikasikan di Hortonworks.com sebelum merger dengan Cloudera. Beberapa tautan, sumber daya, atau referensi mungkin tidak lagi akurat.

Pos blog ini awalnya muncul di sini dan direproduksi secara keseluruhan di sini.

HBase adalah database terdistribusi yang dibangun di sekitar konsep inti dari log tulis yang dipesan dan pohon gabungan yang terstruktur dengan log. Seperti halnya database apa pun, I/O yang dioptimalkan merupakan perhatian penting bagi HBase. Jika memungkinkan, prioritasnya adalah tidak melakukan I/O sama sekali. Ini berarti bahwa pemanfaatan memori dan struktur caching adalah yang paling penting. Untuk tujuan ini, HBase memelihara dua struktur cache:"memory store" dan "block cache". Penyimpanan memori, diimplementasikan sebagai MemStore , mengumpulkan hasil edit data saat diterima, menyimpannya di memori (1). Cache blok, implementasi dari BlockCache antarmuka, menyimpan blok data tetap di memori setelah dibaca.

 MemStore penting untuk mengakses suntingan terbaru. Tanpa MemStore , mengakses data tersebut seperti yang ditulis ke dalam log tulis akan memerlukan pembacaan dan deserialisasi entri kembali dari file tersebut, setidaknya O(n) operasi. Sebagai gantinya, MemStore mempertahankan struktur daftar lewati, yang menikmati O(log n) biaya akses dan tidak memerlukan disk I/O. MemStore hanya berisi sebagian kecil dari data yang disimpan di HBase.

Melayani pembacaan dari BlockCache adalah mekanisme utama di mana HBase mampu melayani pembacaan acak dengan latensi milidetik. Saat blok data dibaca dari HDFS, blok tersebut disimpan dalam cache di BlockCache . Pembacaan selanjutnya dari data tetangga – data dari blok yang sama – tidak mengalami penalti I/O untuk mengambil kembali data tersebut dari disk (2). Ini adalah BlockCache yang akan menjadi fokus tersisa dari postingan ini.

Memblokir cache

Sebelum memahami BlockCache , ini membantu untuk memahami apa sebenarnya "blok" HBase itu. Dalam konteks HBase, blok adalah satu unit I/O. Saat menulis data ke HFile, blok adalah unit terkecil dari data yang ditulis. Demikian juga, satu blok adalah jumlah data terkecil yang dapat dibaca kembali oleh HBase dari HFile. Berhati-hatilah untuk tidak mengacaukan blok HBase dengan blok HDFS, atau dengan blok sistem file yang mendasarinya – ini semua berbeda (3).

Blok HBase tersedia dalam 4 variasi: DATAMETAINDEX , dan BLOOM .

DATA memblokir menyimpan data pengguna. Saat BLOCKSIZE ditentukan untuk keluarga kolom, ini adalah petunjuk untuk jenis blok ini. Ingat, itu hanya petunjuk. Saat membersihkan MemStore , HBase akan melakukan yang terbaik untuk menghormati pedoman ini. Setelah setiap Cell ditulis, penulis memeriksa apakah jumlah yang tertulis>=target BLOCKSIZE . Jika demikian, blok saat ini akan ditutup dan blok berikutnya akan dimulai (4).

INDEX dan BLOOM blok melayani tujuan yang sama; keduanya digunakan untuk mempercepat jalur baca. INDEX blok memberikan indeks di atas Cell s terkandung dalam DATA blok. BLOOM blok berisi filter mekar pada data yang sama. Indeks memungkinkan pembaca mengetahui dengan cepat di mana Cell harus disimpan. Filter memberi tahu pembaca saat Cell pasti tidak ada dalam data.

Terakhir, META blok menyimpan informasi tentang HFile itu sendiri dan berbagai informasi lainnya – metadata, seperti yang Anda harapkan. Ikhtisar yang lebih komprehensif tentang format HFile dan peran berbagai jenis blok tersedia di Apache HBase I/O – HFile.

HBase BlockCache dan implementasinya

Ada satu BlockCache instance di server wilayah, yang berarti semua data dari semua wilayah yang dihosting oleh server tersebut berbagi kumpulan cache yang sama (5). BlockCache dipakai saat startup server wilayah dan dipertahankan selama masa proses. Biasanya, HBase hanya menyediakan satu BlockCache implementasi: LruBlockCache . Rilis 0.92 memperkenalkan alternatif pertama di HBASE-4027: SlabCache . HBase 0.96 memperkenalkan opsi lain melalui HBASE-7404, yang disebut BucketCache .

Perbedaan utama antara LruBlockCache yang teruji dan benar dan alternatif ini adalah cara mereka mengelola memori. Khususnya, LruBlockCache adalah struktur data yang berada sepenuhnya di tumpukan JVM, sementara dua lainnya dapat memanfaatkan memori dari luar tumpukan JVM. Ini adalah perbedaan penting karena memori tumpukan JVM dikelola oleh Pengumpul Sampah JVM, sementara yang lain tidak. Dalam kasus SlabCache dan BucketCache , idenya adalah untuk mengurangi tekanan GC yang dialami oleh proses server wilayah dengan mengurangi jumlah objek yang disimpan di heap.

LruBlockCache

Ini adalah implementasi default. Blok data di-cache di tumpukan JVM menggunakan implementasi ini. Ini dibagi menjadi tiga area:akses tunggal, multi-akses, dan dalam memori. Area berukuran 25%, 50%, 25% dari total BlockCache ukuran, masing-masing (6). Blok yang awalnya dibaca dari HDFS diisi di area akses tunggal. Akses berturut-turut mempromosikan blok itu ke area multi-akses. Area dalam memori dicadangkan untuk blok yang dimuat dari kelompok kolom yang ditandai sebagai IN_MEMORY . Terlepas dari areanya, blok lama digusur untuk memberi ruang bagi blok baru menggunakan algoritme yang Paling Jarang Digunakan, oleh karena itu "Lru" di "LruBlockCache".

SlabCache

Implementasi ini mengalokasikan area memori di luar heap JVM menggunakan DirectByteBuffer s. Area ini menyediakan isi BlockCache . ini . Area yang tepat di mana blok tertentu akan ditempatkan didasarkan pada ukuran blok. Secara default, dua area dialokasikan, masing-masing menghabiskan 80% dan 20% dari total ukuran cache off-heap yang dikonfigurasi. Yang pertama digunakan untuk cache blok yang kira-kira ukuran blok target (7). Yang terakhir memegang blok yang kira-kira 2x ukuran blok target. Sebuah balok ditempatkan di area terkecil yang dapat ditampungnya. Jika cache bertemu dengan blok yang lebih besar dari yang dapat ditampung di salah satu area, blok itu tidak akan di-cache. Suka LruBlockCache , penggusuran blok dikelola menggunakan algoritme LRU.

BucketCache

Implementasi ini dapat dikonfigurasi untuk beroperasi dalam salah satu dari tiga mode berbeda: heapoffheap , dan file . Apa pun mode operasinya, BucketCache mengelola area memori yang disebut "bucket" untuk menyimpan blok yang di-cache. Setiap ember dibuat dengan ukuran blok target. heap implementasi membuat ember tersebut di tumpukan JVM; offheap implementasi menggunakan DirectByteByffers untuk mengelola ember di luar tumpukan JVM; file mode mengharapkan jalur ke file di sistem file tempat bucket dibuat. file mode dimaksudkan untuk digunakan dengan penyimpanan cadangan berlatensi rendah – sistem file dalam memori, atau mungkin file yang tersimpan di penyimpanan SSD (8). Apa pun modenya, BucketCache membuat 14 ember dengan ukuran berbeda. Ini menggunakan frekuensi akses blok untuk menginformasikan pemanfaatan, seperti LruBlockCache , dan memiliki perincian akses tunggal, multiakses, dan dalam memori yang sama sebesar 25%, 50%, 25%. Juga seperti cache default, penggusuran blok dikelola menggunakan algoritme LRU.

Cache Multi-Level

Baik SlabCache dan BucketCache dirancang untuk digunakan sebagai bagian dari strategi caching multi-level. Jadi, sebagian dari total BlockCache ukuran dialokasikan ke LruBlockCache contoh. Instans ini bertindak sebagai cache tingkat pertama, "L1," sedangkan instans cache lainnya diperlakukan sebagai cache tingkat kedua, "L2." Namun, interaksi antara LruBlockCache dan SlabCache berbeda dari cara LruBlockCache dan BucketCache berinteraksi.

 SlabCache strategi, yang disebut DoubleBlockCache , adalah untuk selalu menyimpan blok di cache L1 dan L2. Kedua level cache beroperasi secara independen:keduanya diperiksa saat mengambil blok dan masing-masing mengeluarkan blok tanpa memperhatikan yang lain. BucketCache strategi, yang disebut CombinedBlockCache , menggunakan cache L1 secara eksklusif untuk blok Bloom dan Index. Blok data dikirim langsung ke cache L2. Jika terjadi pengusiran blok L1, alih-alih dibuang seluruhnya, blok tersebut diturunkan ke cache L2.

Mana yang harus dipilih?

Ada dua alasan untuk mempertimbangkan untuk mengaktifkan salah satu alternatif BlockCache implementasi. Yang pertama hanyalah jumlah RAM yang dapat Anda dedikasikan ke server wilayah. Kebijaksanaan komunitas mengakui batas atas tumpukan JVM, sejauh menyangkut server wilayah, berada di antara 14GB dan 31GB (9). Batas yang tepat biasanya tergantung pada kombinasi profil perangkat keras, konfigurasi cluster, bentuk tabel data, dan pola akses aplikasi. Anda akan tahu bahwa Anda telah memasuki zona bahaya saat GC berhenti dan RegionTooBusyException s mulai membanjiri log Anda.

Waktu lain untuk mempertimbangkan cache alternatif adalah saat latensi respons benar-benar penting. Menjaga tumpukan di sekitar 8-12GB memungkinkan kolektor CMS berjalan sangat lancar (10), yang memiliki dampak terukur pada persentil ke-99 waktu respons. Dengan adanya batasan ini, satu-satunya pilihan adalah menjelajahi pengumpul sampah alternatif atau mengambil salah satu implementasi off-heap ini.

Opsi kedua ini persis seperti yang telah saya lakukan. Dalam postingan saya berikutnya, saya akan membagikan beberapa hasil eksperimen yang tidak ilmiah namun informatif di mana saya membandingkan waktu respons untuk BlockCache yang berbeda implementasi.

Seperti biasa, pantau terus dan ikuti terus HBase!

1:The MemStore mengumpulkan hasil edit data saat diterima, menyimpannya di memori. Ini melayani dua tujuan:meningkatkan jumlah total data yang ditulis ke disk dalam satu operasi, dan mempertahankan perubahan terbaru dalam memori untuk akses selanjutnya dalam bentuk pembacaan latensi rendah. Yang pertama penting karena membuat potongan penulisan HBase secara kasar sinkron dengan ukuran blok HDFS, menyelaraskan pola akses HBase dengan penyimpanan HDFS yang mendasarinya. Yang terakhir ini cukup jelas, memfasilitasi permintaan baca ke data yang baru saja ditulis. Perlu ditunjukkan bahwa struktur ini tidak terlibat dalam ketahanan data. Pengeditan juga ditulis ke log penulisan yang diurutkan, HLog , yang melibatkan operasi penambahan HDFS pada interval yang dapat dikonfigurasi, biasanya segera.

2:Membaca ulang data dari sistem file lokal adalah skenario terbaik. Bagaimanapun juga, HDFS adalah sistem file terdistribusi, jadi kasus terburuknya memerlukan membaca blok itu melalui jaringan. HBase melakukan yang terbaik untuk mempertahankan lokalitas data. Kedua artikel ini memberikan pandangan mendalam tentang arti lokalitas data untuk HBase dan cara pengelolaannya.

3:Sistem file, HDFS, dan blok HBase semuanya berbeda tetapi terkait. Subsistem I/O modern adalah banyak lapisan abstraksi di atas abstraksi. Inti dari abstraksi itu adalah konsep satu unit data, yang disebut sebagai "blok". Oleh karena itu, ketiga lapisan penyimpanan ini menentukan bloknya sendiri, dengan ukurannya masing-masing. Secara umum, ukuran blok yang lebih besar berarti peningkatan throughput akses sekuensial. Ukuran blok yang lebih kecil memfasilitasi akses acak yang lebih cepat.

4:Menempatkan BLOCKSIZE memeriksa setelah data ditulis memiliki dua konsekuensi. Satu Cell adalah unit data terkecil yang ditulis ke DATA memblokir. Ini juga berarti Cell tidak dapat menjangkau banyak blok.

5:Ini berbeda dengan MemStore , yang memiliki instance terpisah untuk setiap wilayah yang dihosting oleh server wilayah.

6:Sampai baru-baru ini, partisi memori ini didefinisikan secara statis; tidak ada cara untuk mengesampingkan pembagian 25/50/25. Segmen tertentu, area multi-akses misalnya, dapat tumbuh lebih besar dari alokasi 50% selama area lain kurang dimanfaatkan. Peningkatan pemanfaatan di area lain akan mengusir entri dari area multi-akses hingga saldo 25/50/25 tercapai. Operator tidak dapat mengubah ukuran default ini. HBASE-10263, pengiriman dalam HBase 0.98.0, memperkenalkan parameter konfigurasi untuk ukuran ini. Perilaku fleksibel dipertahankan.

7:Bisnis "kira-kira" adalah untuk memungkinkan beberapa ruang gerak dalam ukuran blok. Ukuran blok HBase adalah target atau petunjuk kasar, bukan batasan yang ditegakkan secara ketat. Ukuran pasti dari blok data tertentu akan bergantung pada ukuran blok target dan ukuran Cell nilai-nilai yang terkandung di dalamnya. Petunjuk ukuran blok ditetapkan sebagai ukuran blok default 64kb.

8:Menggunakan BucketCache dalam file mode dengan penyimpanan dukungan persisten memiliki manfaat lain:ketekunan. Saat startup, ia akan mencari data yang ada di cache dan memverifikasi validitasnya.

9:Seperti yang saya pahami, ada dua komponen yang menyarankan batas atas pada kisaran ini. Pertama adalah batas kemampuan pengalamatan objek JVM. JVM dapat mereferensikan objek di heap dengan alamat relatif 32-bit alih-alih alamat asli 64-bit penuh. Pengoptimalan ini hanya dimungkinkan jika ukuran tumpukan total kurang dari 32 GB. Lihat Ups Terkompresi untuk detail selengkapnya. Yang kedua adalah kemampuan pengumpul sampah untuk mengikuti jumlah churn objek dalam sistem. Dari apa yang saya tahu, tiga sumber churn objek adalah MemStoreBlockCache , dan operasi jaringan. Yang pertama dimitigasi oleh MemSlab fitur, diaktifkan secara default. Yang kedua dipengaruhi oleh ukuran kumpulan data Anda vs. ukuran cache. Yang ketiga tidak dapat membantu selama HBase menggunakan tumpukan jaringan yang bergantung pada salinan data.

10:Sama seperti dengan 8, ini mengasumsikan “hardware modern”. Interaksi di sini cukup kompleks dan jauh di luar cakupan satu entri blog.


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Kinerja HBase CDH5 (HBase1) vs CDH6 (HBase2)

  2. Sinkronisasi Data Cluster HBase dengan alat HashTable/SyncTable

  3. HDFS NameNode Ketersediaan Tinggi di Hadoop

  4. How-to:Gunakan Antarmuka Hemat HBase, Bagian 1

  5. Apa itu Pemadatan HBase?