Skip to content
Snippets Groups Projects

kusancho/governor refactoring

Merged Alexander Kurdakov requested to merge kusancho/governor_refactoring into main
@@ -95,21 +95,21 @@
происходит после того, как будет применено соответствующее изменение
`current_grade`.
Логика изменения собственного `target_grade` до `Offline` реализована в
алгоритме [`sentinel`](../overview/glossary.md#sentinel).
Максимальное время ожидания составляет 3 с и не настраивается. По
истечении времени инстанс в любом случае завершает свою работу.
### Аварийное переключение {: #failover }
За обслуживание отказов инстансов также отвечает raft-лидер. Суть
механизма сводится к тому, что отдельный компонент `sentinel` при
обнаружении отказа инициирует изменение `target_grade = Offline`.
За обслуживание отказов инстансов также отвечает raft-лидер и алгоритм
[`sentinel`](../overview/glossary.md#sentinel), который при обнаружении
отказа инициирует изменение `target_grade = Offline`.
Критерием отказа является невозможность доставки raft-сообщений в течение
5 секунд.
Дальнейшие действия по выводу инстанса из эксплуатации выполняет
`governor`.
<!----------------------------------------------------------------------------->
## Governor — централизованное управление кластером {: #governor }
@@ -117,33 +117,137 @@
Большинство механизмов, связанных с отказоустойчивостью в Picodata, так или иначе
связаны с компонентом governor. С технической точки зрения governor — это
поток управления (fiber), всегда выполняющийся на [raft-лидере](../overview/glossary.md#raft_leader).
Дальше перечислены ответственности губернатора.
Губернатор действует в два этапа. По данным из системных таблиц, которые отражают
состояние кластера, генерируется событие. Например, лидер некоторого репликасета имеет `target_grade` = `Offline`.
Второй этап - реакция на событие, при этом все необходимые действия, предпринимает также губернатор.
Например в случае с недоступностью лидера репликасета, необходимые вызовы RPC, а также записи в глобальные таблицы
будет делать непосредственно губернатор.
### Доступность инстансов {: #instance_reachability }
### Автоматическое переключение узлов, голосующих в raft {: #governor_raft_failover }
Инстанс называется _доступным_ или логически _доступным_, если его
целевой грейд (`target_grade`) не равен `Offline` или `Expelled`.
Физическая доступность хоть и связана с этим понятием, но это не одно и
то же. Например, инстанс, адрес которого стал аргументом команды
[`picodata expel`](../reference/cli.md#expel), некоторое время будет
считаться логически недоступным, несмотря на его физическую доступность.
Governor следит за выполнение ограничений, описанных [здесь](./raft_failover.md#raft_voter_failover).
Доступный инстанс может участвовать в raft-голосовании и быть
назначенным в лидеры как репликасета, так и raft-группы. Соответственно,
_недоступный_ инстанс такую роль играть не может.
<!--
### Автоматическое назначение мастеров репликасетов {: #replicaset_master_switchover }
Work in progress
Picodata следит за тем, чтобы в каждом
[репликасете](../overview/glossary.md#replicaset) была ровно одна
мастер-реплика. Для этого для губернатора реализован алгоритм
автоматического переключения мастера, срабатывающий в том случае, если
мастер-реплика потеряла связь с кластером. Этот алгоритм, разбит на 2 шага, что увеличивает его надежность,
а также позволяет администратору БД использовать его для ручного
переключения мастера в репликасете.
Первым шагом губернатор ищет репликасет, мастер которого [недоступен](#instance_reachability).
Найдя такой репликасет, губернатор выбирает в нем нового кандидата на
роль мастера. На момент написания этих строк, единственный критерий, по
которому делается выбор, такой: инстанс должен быть [доступен](#instance_reachability).
Однако, в будущем могут быть добавлены дополнительные критерии.
В конце первого шага губернатор изменяет запись в глобальной таблице
[_pico_replicaset](./system_tables.md#_pico_replicaset) для
выбранного репликасета, где в поле `target_master_id` указывается
идентификатор инстанса, ставшего новым мастером.
Вторым шагом губернатор находит в таблице [_pico_replicaset](./system_tables.md#_pico_replicaset)
запись с несовпадающими полями `target_master_id` и `current_master_id`. Такая ситуация возможна либо после
выполнения первого шага алгоритма, либо после ручного назначения мастера администратором.
В случае, если текущий мастер репликасета [доступен](#instance_reachability) для связи, губернатор
отправляет ему [запрос](../architecture/rpc_api.md#proc_replication_demote) на перевод в режим "только для чтения", и получает
от него в ответ его текущее значение [vclock](../overview/glossary.md#vclock).
Дальше отправляется [запрос](../architecture/rpc_api.md#proc_replication_promote) новому мастеру на перевод его в активный режим.
Здесь, при наличии значения vclock от предыдущего мастера, оно используется для
синхронизации перед тем как инстанс станет доступен для записи, что
предотвращает потенциальную потерю данных.
Стоит заметить, что в случае потери связи с текущим мастером, синхронизация не
происходит, и потеря данных из реплицируемых асинхронно таблиц все таки может
произойти.
В конце этого шага губернатор обновляет запись в таблице [_pico_replicaset](./system_tables.md#_pico_replicaset),
актуализируя значение поля `current_master_id`.
Стоит заметить, что второй шаг, если имеется возможность, выполняется в первую очередь.
Губернатор не начинает поиск нового кандидата в мастеры репликасета, пока есть хотя бы один
репликасет с целевым мастером, который отличается от текущего.
<!--
Стоит заметить, что хотя логически первый шаг выполняется перед вторым, в
программном коде они описаны в обратном порядке, так как губернатор не должен
начинать поиск нового кандидата в мастеры репликасета пока есть хотя бы один
репликасет с уже выбранным целевым мастером.
-->
### Автоматическое назначение весов шардирования {: #replicaset_weight_change }
Work in progress
Picodata следит за тем, чтобы [репликасеты](../overview/glossary.md#replicaset)
содержали количество реплик не ниже чем [фактор репликации](../overview/glossary.md#replication_factor)
соответствующего [тира](../overview/glossary.md#tier). До тех пор пока это
условие не будет выполнено, данные на такой репликасет подаваться не будут.
Технически это реализовано при помощи так называемых _весов шардирования_, за
актуальностью которых следит губернатор.
Вес [шардирования](../overview/glossary.md#sharding) определяет то, какая пропорция
[бакетов](../overview/glossary.md#bucket) со всего кластера должна быть распределена
на данный репликасет по сравнению с остальными. Изначально все добавляемые
репликасеты в Picodata имеют нулевой вес, что означает, что данные на них
поступать не будут. И только после того, как в репликасете окажется достаточно
реплик, губернатор автоматически установит ему ненулевой вес, тем самым запустив
в работу подсистему [vshard](../overview/glossary.md#vshard), отвечающую за
перераспределение бакетов.
### Первичное распределение бакетов {: #governor_vshard_bootstrap }
Work in progress
<!-- А вообще нужно ли это событие? Как будто само по себе оно не интересное,
а идея выше написана. -->
[Репликасеты](../overview/glossary.md#replicaset) в Picodata начинают свое
существование с нулевым весом и только в какой-то определенный момент жизненного
цикла кластера появляется первый репликасет с ненулевым весом, на
который можно распределять [бакеты](../overview/glossary.md#bucket). Для этого
у губернатора есть специальный шаг, который выполняется не больше одного раза за
жизнь кластера.
### Автоматическое изменение конфигурации vshard {: #governor_vshard_cfg }
Work in progress
-->
Во время нормальной работы кластера Picodata возможно динамическое изменение
топологии, как штатное, так и не очень: инстансы и репликасеты могут добавляться,
связь между ними может пропадать. При этом Picodata поддерживает безотказный
доступ к данным через [распределенный SQL](./distributed_sql.md). Для этого
все инстансы должны знать информацию о конфигурации кластера, а также
своевременно обновлять состояние подсистемы [vshard](../overview/glossary.md#vshard).
Триггерами для изменения конфигурации vshard служат почти все изменения
топологии — например, добавление нового инстанса, или возвращение в строй инстанса,
потерявшего связь с кластером на какое-то время; а также изменения весов
шардирования ([см. параграф выше](#replicaset_weight_change)).
Как только губернатор обнаруживает такое изменение, он обновляет запись о
целевой конфигурации vshard в глобальной системной таблице, что обеспечивает
отказоустойчивость такого изменения: если raft-лидер выйдет из строя, на его
замену будет избран новый, который продолжит выполнять алгоритм губернатора
с того места, где остановился предыдущий.
Следующим шагом губернатор обнаруживает несовпадение текущей и целевой
конфигураций vshard и приступает к ее актуализации, отправляя [запрос](../architecture/rpc_api.md#proc_sharding) на все
инстансы кластера одновременно. Если хотя бы от одного инстанса не будет получен
положительный результат, этот шаг повторяется.
### Автоматическое переключение узлов, голосующих в raft {: #governor_raft_failover }
Governor следит за выполнение ограничений, описанных [здесь](./raft_failover.md#raft_voter_failover).
### Применение изменений кластерной схемы данных {: #governor_schema_change }
Loading