Модель данных HBase

HBase — это колоночно-ориентированная база данных. И хотя HBase хранит данные в таблицах со строками и столбцами (как это делают реляционные базы данных), не стоит рассматривать эти таблицы как наборы строк с фиксированной схемой. Вместо этого таблицы HBase стоит рассматривать как многомерные структуры данных типа ключ/значение.

Основные объекты

Для начала стоит рассмотреть терминологию HBase:

  • Таблица (Table). Набор из нескольких строк, которые могут иметь один или несколько столбцов, принадлежащих фиксированным семействам столбцов. Каждая схема таблицы определяет только семейство столбцов.

  • Строка (Row). Состоит из ключа строки и столбцов со значениями, связанными с ними. Строки сортируются в алфавитном порядке по ключу строки и хранятся в таком же виде.

  • Ключ строки (Row key). Уникальный идентификатор строки, используемый в качестве первичного ключа. Этот ключ используется для доступа к таблицам HBase.

    РЕКОМЕНДАЦИЯ
    Тщательно продумывайте дизайн ваших ключей. Поскольку строки сортируются по ключу, основная цель состоит в том, чтобы хранить связанные строки рядом друг с другом. Однако следует уделять должное внимание равномерности распределения — с целью избежать ситуации, когда одна часть ключей строк используется намного чаще, чем другие.
  • Столбец (Column). Состоит из семейства столбцов и квалификатора столбца, разделенных двоеточием, например: cf:column1, cf:column2 и так далее.

  • Семейство столбцов (Column family). Логическое и физическое объединение столбцов и их значений — обычно выполняется для улучшения производительности. Семейства столбцов фиксируются при создании таблицы и не могут быть изменены "на лету". Тем не менее, каждая строка таблицы может ничего не хранить в семействе столбцов.

    Семейство столбцов может иметь набор свойств хранения, таких как: следует ли кешировать значения в памяти, методы сжатия данных или кодирования строк, время жизни (TTL) и максимальное количество хранимых версий для значений и так далее.

    ВНИМАНИЕ
    Не рекомендуется иметь более трех семейств столбцов для каждой таблицы.
  • Квалификатор столбца (Column qualifier). Идентификатор столбца, необходимый для предоставления индекса для части данных в семействе столбцов. Хотя семейства столбцов фиксированы, квалификаторы можно менять "на лету", и они могут сильно различаться между строками одной и той же таблицы.

  • Ячейка (Cell). Комбинация строки, семейства столбцов и квалификатора столбца. Содержит значение данных и метку времени, представляющую текущую версию значения.

  • Метка времени (Timestamp). Идентификатор версии значения ячейки. По умолчанию представляет время на Region-сервере, когда значение ячейки было записано в HBase. Вы также можете указать другое значение метки времени.

  • Значение (Value). Часть данных, хранящихся в HBase в определенной комбинации: <Таблица, Ключ строки, Семейство столбцов, Квалификатор столбца, Метка времени>.

Модель данных HBase можно представить в виде следующей структуры данных типа ключ/значение: <Table, Row key, Column family, Column qualifier, Timestamp> → Value

Принцип работы

На логическом уровне данные в HBase организованы в таблицы, индексированные по первичному ключу строки. Вы можете хранить неограниченное количество столбцов для каждого ключа строки. Столбцы организованы в группы, называемые семействами столбцов. Как правило, каждое семейство столбцов объединяет столбцы с одинаковым шаблоном использования и хранения.

Столбцы используются для хранения фрагментов данных, называемых значениями. Каждый столбец определяется именем семейства столбцов и собственным уникальным именем, называемым квалификатором столбца. Столбец может хранить несколько версий одного значения. Разные версии значений имеют разные метки времени.

Допустим, имеется таблица с двумя семействами столбцов и двумя строками, идентифицированными ключами строк. Для каждой комбинации ключа строки и семейства столбцов вы можете определить разные квалификаторы столбцов. Вы также можете добавлять новые квалификаторы столбцов "на лету".

Примерный логический вид такой таблицы показан ниже (где ts — это сокращение "timestamp").

Логическое представление

Ключ строки

Семейство столбцов 1

Семейство столбцов 2

Квалификатор столбца 1

Квалификатор столбца 2

Квалификатор столбца 3

Квалификатор столбца 4

Ключ строки 1

ts1:value1

ts3:value3

ts2:value2

ts6:value6

 — 

Ключ строки 2

ts5:value5

ts4:value4

 — 

 — 

ts8:value8 ts7:value7

В таблице, показанной выше, можно увидеть разреженные данные, так как заполнение столбцов для каждого ключа строки необязательно. Вам не нужно заполнять каждое семейство столбцов для ваших строк. Отсутствие столбца не вызывает нагрузки при сохранении пустых значений, так как на физическом уровне данные хранятся иначе, чем на логическом.

На физическом уровне все значения данных в HBase хранятся в отсортированном виде по ключу строки. Блоки ближайших ключей строк образуют регионы, подробную информацию о которых вы можете найти в статье Архитектура HBase. Данные, соответствующие разным семействам столбцов, хранятся отдельно — в разных HFile. Каждое семейство столбцов использует как минимум один HFile. Это позволяет при необходимости читать данные только из нужного семейства столбцов. Столбцы, принадлежащие одному семейству и одному и тому же ключу строки, также сохраняются в виде списка, отсортированного в алфавитном порядке.

Любой столбец может отсутствовать или присутствовать для каждого ключа строки, так как пустые значения не сохраняются в базе данных.

При удалении определенного значения столбца на физическом уровне оно не удаляется в этот же момент. Вместо этого оно помечается специальным флагом tombstone. Физическое удаление данных происходит позже, при выполнении операции Major compaction.

Помимо ручного удаления старых версий, вы можете настроить автоматическое удаление. На уровне семейства столбцов можно определить такие параметры, как время жизни (TTL) и максимальное количество хранимых версий. Если разница между отметкой времени для конкретной версии и текущим временем больше, чем TTL, такая запись помечается для удаления. Если количество версий для определенного столбца превышает максимальное значение хранимых версий, запись также помечается на удаление.

Условное физическое представление таблицы показано ниже. На рисунке видно, что все данные хранятся в одном регионе, а разные семейства столбцов принадлежат разным HFile внутри этого региона.

datamodel 01 dark
Физическое представление
datamodel 01 light
Физическое представление

Пример

Данный раздел описывает модель данных HBase на конкретном примере.

Допустим, необходимо хранить текстовые статьи. Каждая статья имеет базовые атрибуты, которые меняются очень редко (author, header и другие), и теги, описывающие содержание статьи и помогающие выполнять текстовый поиск по всем статьям (arch, concepts, tutorials и другие). Теги изменяются чаще.

РЕКОМЕНДАЦИЯ
Поскольку данные, соответствующие разным семействам столбцов, хранятся отдельно, необходимо распределить их по частоте использования.

Для данного примера можно создать таблицу articles с двумя семействами столбцов:

  • basic — для хранения данных, которые изменяются редко;

  • tags — для хранения тегов.

Следующий JSON иллюстрирует возможную модель данных для данного примера.

Не стоит рассматривать код ниже как точную иллюстрацию того, как данные хранятся на физическом уровне. Это всего лишь макет, используемый для понимания основных объектов модели данных HBase. JSON больше подходит для описания отображений, используемых в HBase, чем обычная двумерная таблица.

{
    "article1": { (1)
        "basic": { (2)
            "author": { (3)
                1637054560096: "Test author" (4)
            },
            "header": {
                1637056832082: "Test article. Version 3",
                1637055836875: "Test article. Version 2",
                1637054560118: "Test article"
            }
        },
        "tags": {
            "arch": {
                1637054560141: true
            },
            "concepts": {
                1637054560160: true
            },
            "tutorials": {
                1637054564066: true
            }
        }
    },
    "article2": {
        "basic": {
            "author": {
                1637054576501: "Test author2"
            },
            "header": {
                1637054576516: "Test article2"
            }
        },
        "tags": {
            "ref": {
                1637054577512: true
            }
        }
    }
}
1 Верхний уровень пар ключ/значение представляет строки таблицы: article1 и article2 — это ключи строк, уникальные для каждой строки.
2 Второй уровень описывает семейства столбцов, которые одинаковы для каждой строки таблицы: basic и tags.
3 Третий уровень описывает квалификаторы столбцов: author и header — принадлежат семейству столбцов basic; arch, concepts, tutorials и ref — принадлежат семейству столбцов tags. Квалификаторы столбцов не фиксированы, их можно добавлять "на лету". Их набор может отличаться для разных строк.
4 Нижний уровень описывает ячейки — пары временных меток и значений. Благодаря временным меткам поддерживается управление версиями значений.

Таким образом, чтобы получить определенное значение данных, хранимое в HBase, необходимо знать следующий путь: Table > Row Key > Column Family > Column Qualifier > Timestamp. Без определения временных меток вы получаете самые последние данные. Например, если вы попытаетесь получить значение строки с ключом article1 и столбцом basic:header, вы получите самое последнее значение Test article. Version 3. Но если вы дополнительно укажете временную метку (например, 1637054560118), вы получите значение Test article.

hbase(main):005:0> get 'articles', 'article1', {COLUMN => 'basic:header', TIMESTAMP => 1637054560118}
COLUMN                CELL
 basic:header         timestamp=1637054560118, value=Test article
1 row(s)
Took 0.0202 seconds
hbase(main):006:0> get 'articles', 'article1', 'basic:header'
COLUMN                CELL
 basic:header         timestamp=1637056832082, value=Test article. Version 3
1 row(s)
Took 0.0054 seconds

Основные команды, применимые к модели данных, показанной в этом примере, описаны в статье Начало работы с HBase shell.

Нашли ошибку? Выделите текст и нажмите Ctrl+Enter чтобы сообщить о ней