Режим отказоустойчивости DCS#
Примечание
Эта страница переведена при помощи нейросети GigaChat.
Проблема#
Patroni в значительной степени полагается на распределенное хранилище конфигурации (DCS) для решения задачи выборов лидера и обнаружения разделения сети. То есть узлу разрешается запускать PostgreSQL в качестве основного только в том случае, если он может обновить блокировку лидера в DCS. Если обновление блокировки лидера не происходит, PostgreSQL немедленно понижается в должности и запускается только для чтения. В зависимости от того, какой DCS используется, шансы столкнуться с «проблемой» различаются. Например, при использовании Etcd, который используется только для Patroni, шансы близки к нулю, в то время как при использовании K8s API (поддерживается Etcd) это может наблюдаться чаще.
Причины текущей реализации#
Сбой при обновлении блокировки лидера может быть вызван двумя основными причинами:
разделение сети;
повреждение DCS.
В общем случае на одном узле невозможно различить эти две причины, поэтому Patroni предполагает наихудший вариант – разделение сети. В случае разделенной сети другие узлы кластера Patroni могут успешно захватить блокировку лидера и перевести Postgres в разряд основных. Чтобы избежать «split-brain», старый основной узел понижается до истечения срока действия блокировки лидера.
Режим отказоустойчивости DCS#
В Patroni реализована новая специальная опция – режим защиты от сбоев. Он может быть включен только через глобальную динамическую конфигурацию, хранящуюся в ключе DCS. Если режим защиты от сбоев включен и обновление блокировки лидера в DCS не удалось по причинам, отличным от несоответствия версии/значения/индекса, PostgreSQL может продолжать работать в качестве основного, если он может получить доступ ко всем известным членам кластера через REST API Patroni.
Детали низкоуровневой реализации#
В Patroni введен новый, постоянный ключ в DCS, названный
/failsafe.Ключ
/failsafeсодержит все известные члены данного кластера Patroni в данный момент времени.Текущий лидер поддерживает ключ
/failsafe.Член кластера допускается к участию в гонке лидеров и становится новым лидером только в том случае, если он присутствует в ключе
/failsafe.Если кластер состоит из одного узла, ключ
/failsafeбудет содержать только один элемент.В случае «отключения» DCS существующий основной участник соединяется со всеми участниками, представленными в ключе
/failsafe, черезPOST /failsafeREST API и может продолжать работать в качестве основного, если все реплики подтвердят это.Если один из членов не отвечает, первичный узел понижается в должности.
Реплики используют входящие запросы
POST /failsafeREST API как индикатор того, что основной еще жив. Эта информация кешируется в течениеttlсекунд.
Часто задаваемые вопросы#
Почему текущему основному узлу необходимо видеть ВСЕХ остальных членов кластера? Можно ли полагаться здесь на кворум?
Проблема заключается в том, что представление о кворуме может отличаться с точки зрения DCS и Patroni. Хотя узлы DCS должны быть равномерно распределены по зонам доступности, для Patroni такого правила нет, и что более важно, нет механизма для введения и обеспечения соблюдения такого правила. Если большинство узлов Patroni оказывается в проигравшей части разделенной сети (включая основную), а меньшинство узлов находится в выигрышной части, основная должна быть понижена в должности. Только проверка ВСЕХ остальных участников позволяет обнаружить такую ситуацию.
Что делать, если узел удаляется при повреждении DCS?
Если DCS недоступен, проверка «доступны ли ВСЕ остальные члены кластера» выполняется каждый цикл цикла сердцебиения (каждые
loop_waitсекунды). Если под/узел завершен, проверка завершится неудачно и PostgreSQL будет понижен до режима только для чтения и не восстановит работу до тех пор, пока DCS не будет восстановлен.Что произойдет, если все участники кластера Patroni будут потеряны при отключении DCS?
Patroni может быть настроен на создание новой реплики из резервной копии даже тогда, когда у кластера нет лидера. Но если новый участник отсутствует в ключе
/failsafe, он не сможет захватить блокировку лидера и повысить его.Что произойдет, если основная система потеряет доступ к DCS, а реплики – нет?
Основная система выполнит код отказа и свяжется со всеми известными репликами. Эти реплики будут использовать эту информацию в качестве индикатора того, что первичный сервер жив, и не начнут гонку за лидером, даже если блокировка лидера в DCS истекла.
Как включить режим отказоустойчивости?
Прежде чем включать
failsafe_mode, убедитесь, что версия Patroni на всех участниках обновлена. После этого можно использовать либоPATCH /configAPI REST, либо patronictl edit-config -s failsafe_mode=true