Подсистемы распространения метаданных: StateStorage, Board, SchemeBoard

В кластере YDB работают три взаимосвязанные подсистемы, которые обеспечивают распространение метаданных между узлами: StateStorage, Board и SchemeBoard. Каждая из них решает свою задачу, но все три построены на одном архитектурном принципе — распределённом кворумном сервисе с детерминированной адресацией реплик.

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

Зачем нужны подсистемы распространения метаданных

Кластер YDB — это распределённая система, в которой одновременно могут работать миллионы таблеток на тысячах узлов. Чтобы компоненты кластера могли взаимодействовать друг с другом, им необходимо знать:

  • где сейчас работает лидер конкретной таблетки и как к нему обратиться (StateStorage);
  • какие узлы предоставляют те или иные сервисы, например, точки подключения для клиентов (Board);
  • какова актуальная схема базы данных (SchemeBoard).

Распространять эти данные с одного узла кластера плохо — это создает высокую нагрузку и проблемы при выходе из строя этого узла. Поэтому метаданные распределяются по множеству узлов кластера с помощью трёх специализированных подсистем.

Подсистемы

StateStorage — хранилище состояния таблеток

StateStorage — это распределённый сервис, который хранит актуальное состояние таблеток: где работает лидер, каков его идентификатор актора, поколение и шаг.

Что хранит StateStorage

Для каждой таблетки StateStorage хранит:

  • Текущий лидер — идентификатор актора (ActorId) лидера таблетки.
  • Поколение и шаг (generation:step) — монотонно возрастающие счётчики, используемые для разрешения конфликтов при выборе лидера.
  • Список фолловеров — идентификаторы акторов реплик таблетки (если они есть).
  • Блокировка — признак того, что таблетка заблокирована в процессе выбора нового лидера.

Как используется StateStorage

StateStorage выполняет роль службы разрешения имён таблеток: любой узел кластера может по TabletId узнать ActorId текущего лидера и напрямую обратиться к нему.

StateStorage также участвует в процессе выбора лидера таблетки. Когда таблетка запускается или перезапускается, она регистрирует себя в StateStorage и получает подтверждение от кворума реплик.

Примечание

Данные в StateStorage являются волатильными: они хранятся только в памяти реплик и теряются при перезапуске процессов. StateStorage не является постоянным хранилищем — он содержит только ту информацию, которую легко восстановить как при запуске таблеток, так и при запуске самих реплик.

Адресация в StateStorage

Выборка реплик для конкретной таблетки вычисляется по её TabletId. Это означает, что реплики разных таблеток могут находиться на разных узлах, что обеспечивает равномерное распределение нагрузки.

Board — доска объявлений сервисов

Board — это распределённый сервис для публикации и поиска метаданных в формате «путь → набор записей». Он работает по модели «публикация — подписка»: один или несколько акторов публикуют информацию по некоторому пути, а другие акторы подписываются на этот путь и получают актуальный список публикаций.

Что хранит Board

Board хранит пары «путь → полезная нагрузка» (payload). Несколько акторов могут одновременно публиковать данные по одному пути — Board хранит все публикации и предоставляет их подписчикам в виде списка.

Как используется Board

Основное применение Board — хранение информации об эндпоинтах (точках подключения) баз данных. Когда узел базы данных запускается, он публикует свой адрес в Board по пути, соответствующему имени базы данных. Клиенты и другие компоненты кластера подписываются на этот путь и получают актуальный список доступных эндпоинтов.

Механизм работы:

  1. Актор-публикатор регистрирует запись в Board по заданному пути.
  2. Актор-подписчик запрашивает список записей по пути и получает уведомления об изменениях.

В отличие от StateStorage, Board не привязан к конкретным таблеткам — он предназначен для произвольных сервисов, которым нужно сделать некоторые данные легко доступными в кластере.

Адресация в Board

Выборка реплик для конкретного пути вычисляется по хешу от этого пути. Это обеспечивает детерминированную маршрутизацию: все публикации и подписки по одному пути попадают на одни и те же реплики.

SchemeBoard — распространение схемных метаданных

SchemeBoard — это распределённый сервис для хранения и распространения метаданных о схеме баз данных: таблицах, индексах, правах доступа и других схемных объектах.

Что хранит SchemeBoard

SchemeBoard хранит описания схемных объектов: таблиц, директорий, индексов, топиков и других объектов схемы. Для каждого объекта хранится его полное описание, включая структуру, настройки и права доступа.

Как используется SchemeBoard

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

Механизм работы:

  1. При изменении схемы SchemeShard публикует обновление в SchemeBoard.
  2. Узлы баз данных подписываются на изменения нужных им схемных объектов и получают уведомления об обновлениях.

Это позволяет узлам баз данных работать с актуальной схемой без постоянных обращений к SchemeShard, что существенно снижает нагрузку на него и уменьшает задержки при выполнении запросов.

Адресация в SchemeBoard

Выборка реплик для конкретного схемного объекта вычисляется по хешу от пути к этому объекту. Это обеспечивает детерминированную маршрутизацию запросов к схемным метаданным.

Сравнение подсистем

Характеристика StateStorage Board SchemeBoard
Назначение Хранение состояния таблеток Публикация метаданных сервисов Распространение схемных метаданных
Тип данных Состояние лидера таблетки (ActorId, generation:step) Произвольные пары путь → payload Описания схемных объектов
Ключ адресации TabletId Путь (строка) Путь к схемному объекту
Основные потребители Tablet Pipe gRPC-прокси, клиенты (поиск эндпоинтов) Узлы баз данных (кеш схемы)
Источник данных Сами таблетки (при запуске/выборе лидера) Акторы-публикаторы SchemeShard

Детерминированная выборка реплик

Каждая запись в подсистеме адресуется по идентификатору — например, TabletId для StateStorage или путь к схемному объекту для SchemeBoard. По этому идентификатору с помощью хеш-функции вычисляется фиксированный набор реплик, на которых хранится данная запись.

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

Кворум

Для работы с каждой записью выбирается определенное количество реплик nto_select. Операции записи система пытается выполнять со всеми nto_select репликами, но при этом допускается отказ меньшинства реплик, и такой отказ не приводит к временной недоступности или приостановке работы.
Для успешного выполнения операции с записью достаточно получить ответ от большинства выбранных реплик — то есть от nto_select / 2 + 1 реплик, где nto_select — общее число реплик в выборке. Это означает, что часть реплик может быть недоступна, и подсистема продолжит работать.

Именно кворумный принцип позволяет безопасно выводить узлы на обслуживание и выполнять роллинг-рестарты кластера без потери работоспособности.

Ключевые понятия

Реплика

Реплика — это актор, работающий на узле кластера и хранящий часть метаданных подсистемы. Реплика принимает запросы на чтение и запись, участвует в формировании кворума.

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

Кольцо

Мотивация

Для равномерного распределения нагрузки по узлам кластера подсистемам может потребоваться большое количество реплик: чем их больше, тем меньше запросов приходится на каждую реплику. Однако с ростом числа реплик возникает вопрос отказоустойчивости: при отказе домена отказа (серверной стойки) из строя одновременно может выйти несколько реплик, и это скажется на кворуме.

Определение и принцип работы

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

Кольца и домены отказа

Реплики каждого кольца размещаются в пределах одного домена отказа (fail domain) — одной, или нескольких серверных стойках. Реплики из разных колец при этом размещаются в разных стойках. Не допускается чтобы в одной стойке оказались реплики из разных колец. Это гарантирует, что при выходе из строя любой стойки из каждой выборки потеряется не более одной реплики — той, что принадлежит кольцу, чьи реплики находились в этой стойке.

Кольца и области отказа

В кластерах с несколькими областями отказа (fail realm) — например, дата-центрами — применяются дополнительные ограничения на размещение реплик по кольцам:

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

Эти ограничения позволяют контролировать, сколько колец затронет выход из строя целого дата-центра: если каждая область отказа содержит не более k колец, то при её отказе из строя выйдет не более k реплик из каждой выборки.

Группа колец

Группа колец — это набор колец, по которому собирается отдельный кворум. Подсистема может одновременно работать с несколькими группами колец, собирая кворум в каждой из них независимо.

Группы колец — это механизм бесшовного изменения конфигурации. Они позволяют вводить новые наборы реплик и выводить старые без остановки кластера. Подробнее об этом — в разделе Группы колец и смена конфигурации.

Группы колец и смена конфигурации

Бесшовная смена конфигурации

Изменение конфигурации подсистем — например, перенос реплик на другие узлы или изменение числа реплик — выполняется через добавление и удаление групп колец. Это позволяет менять конфигурацию без остановки кластера и без потери доступности.

Процесс смены конфигурации состоит из нескольких шагов:

  1. Добавляется новая группа колец с нужной конфигурацией. На этом этапе она помечается флагом write_only — это означает, что новая группа получает все записи (синхронизируется с данными), но не участвует в кворуме на чтение. Запросы на чтение по-прежнему обслуживает старая группа.
  2. После того как новая группа синхронизировалась и стала полноценной, флаг write_only снимается. Теперь обе группы участвуют в кворуме.
  3. Старая группа помечается флагом write_only, а новая становится основной.
  4. Старая группа удаляется.

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

Подробные инструкции по ручной смене конфигурации приведены в разделе Конфигурирование подсистем распространения метаданных.

Автоматическая реконфигурация (Self Heal)

В кластерах с конфигурацией V2 доступен механизм Self Heal State Storage — автоматическое управление конфигурацией подсистем. Он отслеживает состояние узлов кластера и при необходимости:

  • переносит реплики с вышедших из строя узлов на работоспособные;
  • добавляет новые реплики при расширении кластера.

Self Heal работает через тот же механизм групп колец, что и ручная реконфигурация, но выполняет все шаги автоматически. Подробнее — в разделе Self Heal State Storage.

Группы колец в конфигурации двух дата-центров

В конфигурации с двумя дата-центрами (режим bridge) каждый дата-центр (pile) имеет собственную группу колец. Это позволяет:

  • каждому дата-центру работать автономно, собирая кворум внутри своей группы;
  • быстро и бесшовно переключать, какой дата-центр является основным (primary), без изменения конфигурации реплик.

Подробнее о режиме bridge описано в разделе Режим bridge.

Отказоустойчивость и модель отказа

Подсистемы распространения метаданных спроектированы с учётом модели отказа YDB, основанной на концепциях доменов отказа (обычно — серверных стоек) и областей отказа (обычно — дата-центров).

Правило размещения реплик (разные кольца — в разных стойках; реплики одного кольца могут быть в одной или нескольких стойках) обеспечивает следующие гарантии:

  • Отказ отдельного узла: теряется не более одной реплики из каждой выборки. Кворум сохраняется.
  • Отказ целой стойки: поскольку все реплики одного кольца находятся в одной стойке, теряется ровно одна реплика из каждой выборки. При nto_select = 5 кворум (3 из 5) сохраняется даже при потере целой стойки.
  • Роллинг-рестарт: последовательный перезапуск узлов не нарушает кворум, так как в каждый момент времени недоступна лишь часть реплик.