Страницы

суббота, 16 ноября 2013 г.

Hbase, часть 2 Регионы, запись в Hadoop

       Hadoop спроектирован таким образом, что редактировать содержимое файла нельзя, только добавлять или удалить  весь. Второй аспект hadoop в том, что это Offline система, и совсем  не предназначенная для Online операций, кроме конечно собственно добавления новых данных. В то же время Hdfs позиционируется как хранилище высокой доступности. Отсюда для меня не тривиально, как  на основе Hadoop построили online хранилище  Hbase . Ниже физика процесса работы hbase с hadoop.



      Hadoop поддерживает два типа файлов SequenceFile и MapFile,  в первый тип файлов можно добавлять записи, и что бы добраться до нужной по сути придеться просмотреть весь файл. MapFile по сути является директорией с тем самым  SequenceFile и файлом индекса(
 /data - файл с данным и /index - индекс). И MapFile поддерживает добавление отсортированых пар ключ-значение, и каждая N-ая запись будет заноситься в индекс со смещение - то есть получаем индекс поиск, по которому эквивалентен log N + N, N естественно настраивается.     Что дальше! Hbase хранит последнии изменениея ключе в памяти, это настраивается параметрами конфигурации memstore*что-то там, и естественно их сортирует для добавления в исходный MapFile, смотрите конфигурационные параметры flush - можно задавать интервалы записи на диск и тп.  Для решения проблемы  удаления записи  - есть специальное поле, то есть удаляемая запись добавляется с флагом, что я мол удалена, а проблема замены конкретного "ключа -значения" решается поиском ключа с последним timestamp - то есть ваш файл таблицы хранит по сути всю историю изменений.

   Здесь есть один изъян -  есть MapFile с осортироваными значениями, и мы уже не можем добавить в него новую порцию, потому эта порция  может нарушить ( с вероятностью 0.99)  условие осортированости всех данных. То есть Hbase создает новый файл и поиск уже будет происходить среди двух отсортированых файлов, потом трех, четырех и так далее. Что есть естественно не очень хорошо, при планомерном увеличение объема. Мы подходим к следующему понятию compact и  compact major. Это операции, которые делает Hbase время от времени с таблицей и регионами - и означают они, как вы уже  возможно догадались следующей - свертку всего этого зоопарка MapFile-в в один большой - что естественно есть гуд для "поиска", но не есть гуд для доступности региона или таблицы( compact major ), ведь данные могут быть ооочень большими. Я не буду говорить что нужно делать регионы, как можно меньше, потому что есть и аргументы против этой политики, но все же однозначно большие регионы с активной записью в них, не есть хорошо. А да у нас появилось новое понятие Регион.
       Регион - это основная логическая единица HBase. Есть кучу других, но планирование
регионов это именно то, что по сути Hbase и делает легко масштабируемым, и почему
compaction не смотря на всю ужасность  этой  операции не занимает часы! Представляете себе
файл гигобайтовский  - отсортировать заново с учетом новой порции пары мегабайт данных.

Почему легко справляются с этим традиционные СУБД - потому что "обычно" есть в таблице волшебный первичный ключ, который используется для вставки в бинарное дерево, но данная статья не об этом.

Каждая таблица Hbase состоит из :
Table       (таблица Hbase)
   Region       (Регионы для таблицы)
     Store          (Хранилище для группы ключей для каждого региона в таблице)
              MemStore  ( тот самый буффер в памяти)
              StoreFile    (Файлы )      
                    Block             (Блоки файла ) 
 
           
      Что такое MemStore думаю вы уж себе представили себе, что такое Файл тоже уже понимаете. А что такое Регион. Каждая таблица разбита на регионы - в идеальном случае ваша гигабайтовская таблица будет допустим представлена 10-ью регионами по 128 мегабайт каждый, которые разбиты будут допустим по пяти серверам ( по два на каждый сервер). У региона самое важное свойство это ключ, с которого он начинаетс и ключ  которым он заканчивается, то есть тот самый индекс только на другом уровне.  Обычно название региона выглядит так

bariernaya_kontracepciyaclient_device_link,e005254e51c43aa9377416294d0a13da,1383756450924.9b1a10cb605165fbc11d688cb43839dd.

bariernaya_kontracepciyaclient_device_link - название таблицы
e005254e51c43aa9377416294d0a13da - стартовый ключ
9b1a10cb605165fbc11d688cb43839dd. - конечный ключ
1383756450924 - случайное число подозрительно похожее на timestamp

         Каждый регион прикрепляется к регион-серверу кластера(операции assign), за это отвечает мастер сервер.  И обогащенные этим знанием давайте рассмотри операции
записи и чтения ( удаления не будем, потому что мы выяснили, что это та же запись)

Запись/Чтение - приходит запрос на сервер Rest или Thrift, из метатаблицы сервер знает, какой регион отвечает за ключ ( помните все ключи отсортированы, то есть начального и конечного значения достаточно для определения региона ), соответственно известен и регион-сервер который за все это отвечает  и запрос отправляется на обработку  к нему, там уже ключ записывается в MemStore и WalLog.
     WalLog -  это наша защита от сбоев, если всееее пошло не так, грубо говоря это журнал всееееех изменений на данном регион сервере, он используется для восстановления после пооолного краха, распределении утеряных ключей  регион-сервера, вы скажете, как так, если машина упала, то почему ее лог доступен, так это детка Hadoop, там минимум три реплики, первая сосбственно на исходной машине, и вторые две, еще где-то на двух машинах.
        Поэтому регион-сервер сортирует не гигабайтный файл, а его маленькую часть во время операции compaction, которую вы можете задавать как в ручную так и в конфиге. Кроме всего прочего запрос может попасть в MemStore ( CachHiting - вроде обозвали), то есть в оперативную память, что собственно неплохо.

     А теперь самое главное Hbase умеет  сам распределять регионы между серверами. Не не так. Hbase умеет  сам распределять регионы между серверами. То есть по каким-то независящим от здравого смысла причинам регион сервер стал недоступен у него бывает.
Тогда Hbase начинает распределять все регионы по оставшимся регион-серверам. Какое-то время регионы побудут в состояние transition,  конечно же будут глюки с  некоторыми ключами(а как им не быть), но кластер будет отвечать на запросы, которые не связаны с массивом проблемных ключей, принадлежащих проблемному регион-серверу.

     Из всего изложенного делаем вывод..
Необходимо при работе Hbase :

   1) планировать ключ
  2 ) планировать распределение, грубо говоря кол-во регионов на каждый регион - сервер.

Об этом поговорим позже


     



















2 комментария:

malinos комментирует...

Замечательная статья! Сразу все стало понятно! Спасибо!

Богдан комментирует...

Хоть кому-то полезен этот бложек