Перейти к основному содержимому

Режимы репликации

примечание

Эта страница переведена при помощи нейросети GigaChat.

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

Долговечность асинхронного режима

В асинхронном режиме кластеру разрешено терять некоторые зафиксированные транзакции, чтобы обеспечить доступность. Когда основной сервер выходит из строя или становится недоступен по любой другой причине, Patroni автоматически повышает статус достаточно здорового резервного сервера до основного. Любые транзакции, которые не были реплицированы на этот резервный сервер, остаются в «разветвленной временной шкале» на основном сервере и фактически невосстановимы (анные все еще там, но их восстановление требует ручного восстановления и усилий специалистов по восстановлению данных. Когда Patroni разрешено перематывать с помощью use_pg_rewind, разветвленная временная шкала будет автоматически стерта, чтобы снова соединить сбойный основной сервер с кластером).

Количество транзакций, которые могут быть потеряны, контролируется с помощью параметра maximum_lag_on_failover. Поскольку позиция журнала транзакций основного сервера не выбирается в реальном времени, на самом деле объем потерянных данных при отказе составляет максимально допустимое значение maximum_lag_on_failover байт журнала транзакций плюс то, что записывается за последние ttl секунд (loop_wait/2 секунды в среднем случае). Однако типичная задержка устойчивой репликации значительно меньше одной секунды.

По умолчанию, когда проводятся выборы лидера, Patroni не учитывает текущую временную шкалу реплик, что в некоторых случаях может быть нежелательным поведением. Можно предотвратить превращение узла, у которого нет той же временной шкалы, что и у предыдущего основного устройства, в нового лидера, изменив значение параметра check_timeline на true.

Синхронная репликация PostgreSQL

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

В средах хостинга центров обработки данных (например, AWS, Rackspace или любая сеть, которая не контролируется) синхронная репликация значительно увеличивает изменчивость производительности записи. Если последователи становятся недоступными от лидера, лидер фактически становится доступным только для чтения.

Чтобы включить простой тест синхронной репликации, добавьте следующие строки в раздел parameters файлов конфигурации YAML:

synchronous_commit: "on"
synchronous_standby_names: "*"

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

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

Синхронный режим

Для случаев использования, когда потеря завершенных транзакций недопустима, можно включить synchronous_mode Patroni. При включенном synchronous_mode Patroni не будет продвигать резервную систему, если не будет уверен, что резервная система содержит все транзакции, которые могли вернуть статус успешной фиксации клиенту. Это означает, что система может быть недоступна для записи, даже если некоторые серверы доступны. Системные администраторы могут использовать команды ручного обхода отказа для продвижения резервного сервера, даже если это приведет к потере транзакций.

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

Если включен режим synchronous_mode и произошел сбой резервного сервера, коммиты будут блокироваться до тех пор, пока не запустится следующая итерация Patroni и не переключит основной сервер в автономный режим (в худшем случае задержка на запись ttl секунд, в среднем - loop_wait/2 секунды). Ручное выключение или перезапуск резервного сервера не приведет к прерыванию сервиса фиксации. Standby подаст первичному серверу сигнал об освобождении от обязанностей синхронного standby до того, как будет инициировано выключение PostgreSQL.

Когда абсолютно необходимо гарантировать, что каждая запись сохраняется надежно по крайней мере на двух узлах, включите synchronous_mode_strict в дополнение к synchronous_mode. Этот параметр предотвращает отключение синхронной репликации Patroni на основном сервере при отсутствии кандидатов на синхронную резервную копию. Как недостаток, основная база данных недоступна для записи (если явно не отключить транзакцию Postgres synchronous_mode), блокируя все запросы клиентов на запись до тех пор, пока хотя бы одна синхронная реплика не появится.

Можно быть уверенным, что резервная копия никогда не станет синхронной резервной копией, если установить тег nosync в значение true. Рекомендуется установить это значение для резервных копий, которые находятся за медленными сетевыми соединениями и могут вызвать ухудшение производительности при переходе в режим синхронной резервной копии.

Синхронный режим можно включать и выключать через интерфейс Patroni REST. Подробнее см. в разделе «Динамическая конфигурация».

Примечание:

Из-за того, как реализована синхронная репликация в PostgreSQL, существует вероятность потери транзакций даже при использовании synchronous_mode_strict. Если бэкенд PostgreSQL отменяется во время ожидания подтверждения репликации (в результате отмены пакета из-за тайм-аута клиента или сбоя бэкенда), изменения транзакции становятся видимыми для других бэкендов. Эти изменения еще не были воспроизведены и могут быть потеряны в случае повышения уровня резервирования.

Фактор синхронной репликации

Параметр synchronous_node_count используется Patroni для управления количеством синхронных резервных баз данных. По умолчанию он равен 1. Он не влияет, если для параметра synchronous_mode установлено значение off. Если параметр включен, Patroni управляет точным количеством синхронных резервных баз данных на основе параметра synchronous_node_count и корректирует состояние в DCS & synchronous_standby_names по мере присоединения и ухода участников.

Реализация синхронного режима

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

  • Узел должен быть помечен как последний лидер всякий раз, когда он может принимать транзакции записи. Повреждение Patroni или неполное завершение работы PostgreSQL могут привести к нарушению этого инварианта.
  • Узел должен быть установлен как синхронный резервный узел в PostgreSQL до тех пор, пока он публикуется как синхронный резервный узел.
  • Узлу, который не является лидером или текущей синхронной резервной копией, не разрешается автоматически повышать себя.

Patroni будет назначать один или несколько синхронных резервных узлов на основе параметра synchronous_node_count для synchronous_standby_names.

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