HBase
 sql >> база данни >  >> NoSQL >> HBase

Apache HBase I/O – HFile

Въведение

Apache HBase е Hadoop с отворен код, разпределен, версиян мениджър за съхранение, много подходящ за случаен , четене/запис в реално време достъп.

Чакай чакай? произволен достъп за четене/запис в реално време?
Как е възможно това? Hadoop не е ли просто система за последователно четене/запис, пакетна обработка?

Да, говорим за едно и също нещо и в следващите няколко параграфа ще ви обясня как HBase постига произволно I/O, как съхранява данни и еволюцията на формата HFile на HBase.

Входно-изходни файлови формати на Apache Hadoop

Hadoop идва с файлов формат SequenceFile[1], който можете да използвате за добавяне на вашите двойки ключ/стойност, но поради възможността само за добавяне на hdfs, файловият формат не може да позволи промяна или премахване на вмъкната стойност. Единствената разрешена операция е добавяне и ако искате да потърсите определен ключ, трябва да прочетете файла, докато намерите своя ключ.

Както виждате, вие сте принудени да следвате модела на последователно четене/запис... но как е възможно да се изгради произволна система за достъп за четене/запис с ниска латентност като HBase върху това?

За да ви помогне да разрешите този проблем, Hadoop има друг файлов формат, наречен MapFile[1], разширение на SequenceFile. MapFile в действителност е директория, която съдържа два SequenceFile:файла с данни “/data” и индексния файл “/index”. MapFile ви позволява да добавяте сортирани двойки ключ/стойност и всеки N клавиша (където N е конфигурируем интервал) съхранява ключа и отместването в индекса. Това позволява доста бързо търсене, тъй като вместо да сканирате всички записи, вие сканирате индекса, който има по-малко записи. След като намерите своя блок, можете да преминете към истинския файл с данни.

MapFile е хубав, защото можете бързо да търсите двойки ключ/стойност, но все още има два проблема:

  • Как мога да изтрия или заменя ключ/стойност?
  • Когато входът ми не е сортиран, не мога да използвам MapFile.

HBase и MapFile

HBase ключът се състои от:ключ на ред, семейство колони, квалификатор на колона, времеви печат и тип.

За да се реши проблемът с изтриването на двойки ключ/стойност, идеята е да се използва полето „тип“, за да се маркира ключът като изтрит (маркери на надгробната плоча). Решаването на проблема със замяната на двойки ключ/стойност е само въпрос на избиране на по-късен времеви печат (правилната стойност е близо до края на файла, добавяне означава само, че последното вмъкнато е близо до края).

За да решим проблема с „неподредените“ ключове, ние съхраняваме последните добавени ключ-стойности в паметта. Когато достигнете праг, HBase го прехвърля в MapFile. По този начин в крайна сметка добавяте сортирани ключ/стойности към MapFile.

HBase прави точно това[2]:когато добавите стойност с table.put(), вашият ключ/стойност се добавя към MemStore (под капака MemStore е сортиран ConcurrentSkipListMap). Когато се достигне прагът на per-memstore (hbase.hregion.memstore.flush.size) или RegionServer използва твърде много памет за memstore (hbase.regionserver.global.memstore.upperLimit), данните се изтриват на диска като нов MapFile .

Резултатът от всяко изтриване е нов MapFile и това означава, че за да намерите ключ, трябва да търсите в повече от един файл. Това отнема повече ресурси и е потенциално по-бавно.

Всеки път, когато бъде издадено получаване или сканиране, HBase сканира всеки файл, за да намери резултата, за да избегне прескачането на твърде много файлове, има нишка, която ще открие кога сте достигнали определен брой файлове (hbase.hstore.compaction .макс). След това се опитва да ги обедини заедно в процес, наречен уплътняване, който по същество създава нов голям файл в резултат на обединяването на файла.

HBase има два типа уплътняване:едното, наречено „незначително уплътняване“, което просто обединява два или повече малки файла в един, а другото, наречено „основно уплътняване“, което събира всички файлове в региона, ги слива и извършва известно почистване. При голямо уплътняване изтритите ключ/стойности се премахват, този нов файл не съдържа маркерите на надгробната плоча и всички дублиращи се ключове/стойности (операции за замяна на стойност) се премахват.

До версия 0.20 HBase използва формата MapFile за съхраняване на данните, но в 0.20 беше въведен нов специфичен за HBase MapFile (HBASE-61).

HFile v1

В HBase 0.20 MapFile е заменен от HFile:специфична реализация на файл с карта за HBase. Идеята е доста подобна на MapFile, но добавя повече функции от обикновен файл ключ/стойност. Функции като поддръжка на метаданни и индексът вече се съхраняват в един и същ файл.

Блоковете данни съдържат действителните ключ/стойности като MapFile. За всяка „операция за затваряне на блок“ първият ключ се добавя към индекса и индексът се записва в HFile close.

Форматът HFile също така добавя два допълнителни типа блокове „метаданни“:Meta и FileInfo. Тези два блока ключ/стойност се записват при затваряне на файла.

Мета блокът е проектиран да съхранява голямо количество данни със своя ключ като низ, докато FileInfo е проста карта, предпочитана за малка информация с ключове и стойности, които са и байт-масив. StoreFile на Regionserver използва мета-блокове за съхраняване на филтър за Bloom и FileInfo за Max SequenceId, Основен ключ за уплътняване и информация за времевия диапазон. Тази информация е полезна, за да избегнете четенето на файла, ако няма шанс ключът да присъства (Bloom Filter), ако файлът е твърде стар (Max SequenceId) или ако файлът е твърде нов (Timerange), за да съдържа това, което търсим за.

HFile v2

В HBase 0.92 форматът HFile беше променен малко (HBASE-3857), за да се подобри производителността, когато се съхраняват големи количества данни. Един от основните проблеми с HFile v1 е, че трябва да заредите всички монолитни индекси и големи Bloom филтри в паметта и за да разрешите този проблем, v2 въвежда индекси на много нива и Bloom Filter на ниво блок. В резултат на това HFile v2 разполага с подобрена скорост, памет и използване на кеша.

Основната характеристика на тази v2 са „вградени блокове“, идеята е да се разбие индексът и филтърът на Bloom на блок, вместо да има целия индекс и Bloom филтър на целия файл в паметта. По този начин можете да държите в ram точно това, от което се нуждаете.

Тъй като индексът се премества на ниво блок, тогава имате индекс на много нива, което означава, че всеки блок има свой собствен индекс (leaf-index). Последният ключ на всеки блок се запазва, за да се създаде междинен/индекс, който прави многостепенния индекс b+дърво като.

Заглавката на блока вече съдържа известна информация:Полето “Block Magic” беше заменено с полето “Block Type”, което описва съдържанието на блока “Data”, Leaf-Index, Bloom, Metadata, Root-Index и т.н. бяха добавени полета (компресиран/некомпресиран размер и изместен предишен блок), за да се позволи бързо търсене назад и напред.

Кодиране на блокове от данни

Тъй като ключовете са сортирани и обикновено са много сходни, е възможно да се проектира по-добра компресия от това, което може да направи алгоритъм с общо предназначение.

HBASE-4218 се опита да реши този проблем, а в HBase 0.94 можете да избирате между няколко различни алгоритма:Префикс и Diff Encoding.

Основната идея на префиксното кодиране е да се съхранява общият префикс само веднъж, тъй като редовете са сортирани и началото обикновено е същото.

Diff кодирането прокарва тази концепция по-нататък. Вместо да разглежда ключа като непрозрачна последователност от байтове, Diff Encoder разделя всяко ключово поле, за да компресира всяка част по по-добър начин. Това е, че семейството на колоните се съхранява веднъж. Ако дължината на ключа, дължината на стойността и типът са същите като предишния ред, полето се пропуска. Освен това, за повишена компресия, времевата марка се съхранява като разлика от предишната.

Имайте предвид, че тази функция е изключена по подразбиране, тъй като писането и сканирането са по-бавни, но се кешират повече данни. За да активирате тази функция, можете да зададете DATA_BLOCK_ENCODING =PREFIX | DIFF | FAST_DIFF в информацията за таблицата.

HFile v3

HBASE-5313 съдържа предложение за преструктуриране на оформлението на HFile за подобряване на компресията:

  • Опакирайте всички ключове заедно в началото на блока и всички стойности заедно в края на блока. По този начин можете да използвате два различни алгоритма за компресиране на ключ и стойности.
  • Компресирайте времевите марки с помощта на XOR с първата стойност и използвайте VInt вместо long.

Освен това колонен формат или колонно кодиране се разследват, погледнете AVRO-806 за колонен файлов формат от Дъг Кътинг.

Както може да видите, тенденцията в еволюцията е да сте по-наясно какво съдържа файлът, за да получите по-добра компресия или по-добра информираност за местоположението, което се превръща в по-малко данни за запис/четене от диск. По-малко I/O означава повече скорост!

[1] https://clouderatemp.wpengine.com/blog/2011/01/hadoop-io-sequence-map-set-array-bloommap-files/
[2] https://clouderatemp.wpengine. com/blog/2012/06/hbase-write-path/


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Какво представляват HBase уплътненията?

  2. Подобрения в производителността на оперативната база данни в CDP Private Cloud Base 7 срещу CDH5

  3. Използване на Hive за взаимодействие с HBase, част 1

  4. Apache Phoenix за CDH

  5. Бъдещето на Hadoop – заплати и прогнози за работа в анализа на големи данни