Устройство режима bridge
Функциональность Корпоративной СУБД Яндекса
Данная функциональность доступна только в Корпоративной СУБД Яндекса. В open-source версии YDB она отсутствует.
Общее описание режима и сценарии использования см. в статье Режим работы кластера Bridge. Эта статья предназначена для разработчиков и контрибьюторов YDB и содержит технические детали реализации режима bridge.
YDB поддерживает произвольное количество pile, однако для простоты изложения далее рассматривается случай с двумя pile, назовём их pile А и pile Б.
Хранение конфигураций
Distconf хранит конфигурацию двух статических групп, двух наборов state storage, а также scheme board и board. В нём же сохраняется режим работы кластера.
Конфигурация статических групп, state storage и бордов использует схему хранения с двумя комплектами кворумов:
- Кворум А — включает только узлы из pile А. Запись считается успешной, если она прошла на большинстве узлов pile А и на кворуме дисков статической группы pile A;
- Кворум Б — включает только узлы из pile Б. Запись считается успешной, если она прошла на большинстве узлов pile Б и на кворуме дисков статической группы pile Б.
При отказе одного из pile запись в соответствующий кворум становится невозможной.
Distconf использует оба кворума (А и Б) для хранения конфигурации:
- Конфигурация с режимом
PRIMARY/DISCONNECTEDзаписывается только в кворум А; - Конфигурация с режимом
DISCONNECTED/PRIMARYзаписывается только в кворум Б; - Все остальные режимы записываются в оба кворума — А и Б.
При выполнении failover администратор переводит кластер в режим PRIMARY/DISCONNECTED или DISCONNECTED/PRIMARY. В этом режиме конфигурация общих компонентов сохраняется только на кворуме из PRIMARY pile.
Для начала восстановления администратор переводит пару из живого и отказавшего pile в режим PRIMARY/NOT_SYNCHRONIZED. Такая конфигурация сохраняется на всех кворумах.
Запись конфигурации запрещена, если новая конфигурация несовместима с последней сохранённой на узле. Например, переход из PRIMARY/DISCONNECTED в DISCONNECTED/PRIMARY недопустим. Это предотвращает ситуацию, при которой pile А и Б одновременно переключаются в режимы, претендующие на роль PRIMARY.
Для защиты от взаимодействия pile А и pile Б в случае конфликта конфигураций блокируется установка сессий interconnect при обнаружении подобных несоответствий на узлах.
У Distconf при работе в режиме bridge в каждом pile создаётся поддерево, и корни этих поддеревьев присоединяются к лидеру Distconf. Это позволяет при потере pile минимизировать необходимое перестроение связей узлов Distconf.
Запуск статических групп
Конфигурация всех статических групп хранится в Distconf. Корень поддерева Distconf в каждом pile может получить конфигурацию и принять решение о необходимом для применения этой конфигурации кворуме на основании самой конфигурации. DISCONNECTED pile не участвует в кворуме, поэтому для применения конфигурации без DISCONNECTED pile необходимы кворумы А и Б, для применения конфигурации PRIMARY/DISCONNECTED необходим только кворум А, для применения конфигурации DISCONNECTED/PRIMARY необходим только кворум Б.
Когда необходимый кворум собран, Distconf применяет конфигурацию, а Node Warden запускает VDisk и PDisk статических групп.
Для доступа к статической группе используется сервис dsproxy-proxy, который предоставляет таблеткам интерфейс dsproxy и выполняет операции синхронно с обеими группами в паре.
Dsproxy-proxy статической группы меняет режим работы в зависимости от конфигурации, полученной от distconf. Конфигурация dsproxy-proxy хранится в конфигурации общих компонент.
Поведение dsproxy-proxy
В режиме PRIMARY/SYNCHRONIZED запись выполняется синхронно в две группы; чтение выполняется из PRIMARY, и при каждом чтении выполняется ping-запрос во вторую группу, чтобы гарантировать своевременное уведомление о разрыве связи или смене режима работы группы.
В режиме PRIMARY/DISCONNECTED запись и чтение выполняются только в PRIMARY-группе.
В режиме PRIMARY/NOT_SYNCHRONIZED dsproxy-proxy поддерживает несколько подрежимов, определяющих, какие виды записи выполняются в NOT_SYNCHRONIZED-группе:
WRITE_KEEP— выполняется только записьKEEP-флагов;WRITE_KEEP_BARRIER_DONOTKEEP— выполняется запись барьеров,KEEP- иDO_NOT_KEEP-флагов;WRITE_KEEP_BARRIER_DONOTKEEP_DATA— выполняется запись данных, барьеров,KEEP- иDO_NOT_KEEP-флагов.
Конфигурация dsproxy-proxy содержит:
- режим;
- подрежим;
PPGeneration— номер поколения конфигурации dsproxy-proxy;- номер поколения конфигурации dsproxy-группы из pile А;
- номер поколения конфигурации dsproxy-группы из pile Б.
При изменении конфигурации dsproxy-proxy обязательно изменяется номер поколения конфигурации и конфигурации группы для PRIMARY-группы — всегда, для остальных — за исключением состояния DISCONNECTED.
В конфигурацию группы включаются:
- режим;
- подрежим;
PPGeneration— номер поколения конфигурации управляющего dsproxy-proxy.
При каждой операции группа проверяет режим, подрежим и PPGeneration. Это необходимо, чтобы не выполнялись операции от устаревших экземпляров dsproxy-proxy, пропустивших смену режима или подрежима, и чтобы избежать перекрёстного взаимодействия при возникновении двух PRIMARY.
Для перехода из режима PRIMARY/NOT_SYNCHRONIZED в режим PRIMARY/SYNCHRONIZED выполняется синхронизация. В ходе синхронизации недостающие данные переносятся из PRIMARY-группы в NOT_SYNCHRONIZED-группу, а также выполняется двустороннее копирование информации о блокировках.
Bootstrap BSController и других системных таблеток
В списке узлов для запуска таблетки достаточно указать один набор узлов, включающий достаточное количество узлов из каждого pile. Bootstrapper должен анализировать конфигурацию state storage proxy-proxy и на её основе определять, можно ли запускать таблетку на данном узле. Если запуск таблетки на узле невозможен (поскольку узел не находится в PRIMARY-pile), Bootstrapper должен пройти по дереву подключённых к нему Bootstrapper-ов и назначить в качестве запускающего Bootstrapper из PRIMARY-pile. Если такого Bootstrapper-а нет, текущий Bootstrapper не должен запускать таблетку.
Конфигурация и запуск остальных таблеток
Динамическими группами хранения управляет BS Controller. Вместо каждого обычного storage-пула каждый раз создаётся три storage-пула: в пуле А — группы из pile А, в пуле Б — группы из pile Б, в пуле Ц — прокси-прокси группы, составленные из пар групп из пулов А и Б. Управляемые хайвом таблетки используют только прокси-прокси группы из пула Ц.
Запуск таблеток выполняется только в PRIMARY или PROMOTED-pile. Перевоз таблеток из PRIMARY в PROMOTED выполняется по возможности мягко, перевоз таблеток из DISCONNECTED в PRIMARY происходит максимально быстро.
Поведение interconnect
В interconnect разделяются обмен метаданными и установка сессии.
Обмен метаданными происходит до установления сессии и позволяет паре узлов определить используемый набор функций interconnect и обменяться конфигурацией.
Interconnect с узлами из отключённой половины кластера разрывается, и попытки установления соединения не предпринимаются. Установление соединения возможно только после перевода pile в состояние PRIMARY/NOT_SYNCHRONIZED.