Устройство механизма конфигурации V2

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

Конфигурация кластера YDB хранится в нескольких местах и различные компоненты кластера координируют синхронизацию между ними:

  • в виде набора файлов конфигурации узла в файловой системе каждого узла YDB (необходимы для использования в момент запуска узла для подключения к остальному кластеру);
  • в специальной области хранения метаданных на каждом PDisk (кворум из PDisk считается единственным источником правды о конфигурации);
  • в локальной базе таблетки DS Controller (для нужд распределённого хранилища);
  • в локальной базе таблетки Console.

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

Распределённая система конфигурации (Distconf)

Distconf — это система управления конфигурацией V2 кластера YDB, основанная на Node warden, узлах хранения и их PDisk'ах. Все изменения конфигурации V2, включая первоначальную инициализацию, проходят через неё.

Внутренние процессы Distconf

  • Binding
    Узлы хранения формируют ациклический граф. Каждый узел подключается к случайному соседнему таким образом, чтобы не было циклов. В итоге получается дерево из узлов с явно выделенной вершиной-корнем — узлом, который не может никуда подключиться, т.к. все уже подключены к нему. Корневой узел становится лидером, через который проходят все команды и который может принимать решения, в том числе рассылать команды через описанный далее механизм Scatter. Привязка узлов происходит через события TEvInterconnect::TEvNodesInfo и TEvInterconnect::TEvNodeConnected в distconf_binding.cpp.

  • Scatter/Gather
    Лидер рассылает команды другим узлам по сформированному ранее графу (Scatter) и собирает результаты (Gather). Реализовано в distconf_scatter_gather.cpp, задачи рассылки и сбора ответов хранятся в структуре TScatterTasks и исполняются посредством методов IssueScatterTask, CompleteScatterTask и AbortScatterTask.

  • Finite State Machine (FSM)
    В distconf_fsm.cpp реализован конечный автомат, непосредственно управляющий конфигурацией, её изменениями и их распространение по кластеру. Он отвечает за propose и commit изменений, а также смену лидера.

  • Persistent Storage
    Локальная запись и чтение метаданных (TPDiskMetadataRecord) на PDisk'ах с обработкой событий TEvStorageConfigLoaded/TEvStorageConfigStored через TDistributedConfigKeeper.

  • InvokeOnRoot
    Входная точка для команд администратора кластера: запросы TEvNodeConfigInvokeOnRoot обрабатываются в distconf_invoke_common.cpp, ответы возвращаются в виде TEvNodeConfigInvokeOnRootResult.

  • Dynamic
    Узлы баз данных подписываются на события TEvNodeWardenDynamicConfigPush через ConnectToStaticNode, чтобы получать обновления конфигурации в реальном времени.

  • Self-Heal
    При использовании Distconf для статической группы работает Self-Heal по аналогии с динамическими группами.

  • Контроллер распределённого хранилища
    DS-controller получает от Distconf изменения в конфигурации и использует их для работы распределённого хранилища.

  • Локальные YAML-файлы на узлах
    Хранятся в директории, указанной аргументом запуска сервера ydbd --config-dir, и обновляются при получении информации о каждом изменении конфигурации. Эти файлы нужны при старте узла, чтобы обнаружить PDisk'ы и другие узлы кластера, а также установить начальные сетевые соединения. Данные в этих файлах могут быть устаревшими, особенно при выключении узла на длительное время.

Базовый порядок работы Distconf

  1. При старте узла Distconf пытается прочитать конфигурацию с локальных PDisk'ов.
  2. Подключается к случайному узлу хранения для проверки актуальности конфигурации.
  3. Если не удаётся подключиться, но есть кворум подключённых, становится лидером.
  4. Лидер пытается инициировать первоначальную настройку кластера, если она разрешена.
  5. Лидер рассылает актуальную конфигурацию всем узлам через Scatter/Gather.
  6. Узлы сохраняют полученную конфигурацию в локальной области PDisk для метаданных и в директориях --config-dir.

Итоговое распределение конфигурации

Место хранения Содержит
TPDiskMetadataRecord на кворуме из PDisk'ов Истинную актуальную конфигурацию
Локальная директория --config-dir Исходный YAML для старта (может быть устаревшим)
Console Актуальная копия (с минимальной задержкой)
DS-controller Подмножество конфигурации, необходимое для распределённого хранилища