Отказоустойчивость PostgreSQL обеспечивается переключением ролей сервера с Реплики на Мастер СУБД и механизмом потоковой репликации, позволяющим передавать изменения с ведущего сервера на ведомые так, чтобы в каждый момент времени на ведомом сервере хранилась полная и консистентная копия базы данных. Все, что требуется от администратора СУБД в случае сбоя на основном сервере, — это вручную переключить роль мастера на резервный сервер. Но в бизнес-критичных системах нужно, чтобы все операции выполнялись в автоматическом режиме, полностью исключающем моменты недоступности базы данных.

Для обеспечения режима автоматической обработки отказов СУБД PostgreSQL необходимы резервные узлы переключения и дополнительное программное обеспечение, которое не входит в состав поставки. Дополнительная программная «обвязка» обнаруживает сбой основного узла, автоматически производит переключение на резервный узел и, если потребуется, изолирует аварийный узел для исключения ситуации split-brain (появление в кластере одновременно двух узлов, выполняющих роль мастера СУБД). Все эти функции могут выполнять такие программы, как Stolon от компании SorintLab, Patroni от Zalando, Corosync&Pacemaker от ClusterLabs и др. Каждая из них имеет свои преимущества и недостатки, но здесь мы ограничимся разбором программного стека Corosync&Pacemaker, задействующего разные уровни управления и коммуникаций: за управление ресурсами отвечает модуль Pacemaker, а Corosync отвечает за взаимодействие между узлами.

Corosync&Pacemaker — штатное решение обеспечения отказоустойчивости для ОС RedHat/CentOS версий 6, 7, 8, работающее и в ОС Debian, Ubuntu, а также с СУБД PostgreSQL и различными типами сервисов, среди которых веб, базы данных, файловые системы и др. Corosync&Pacemaker берет на себя мониторинг работоспособности узлов кластера, процессов СУБД, а также своих собственных модулей. В случае сбоя на основном узле (мастере) управление передается резервному узлу — реплике. Отказоустойчивый кластер на базе Corosync&Pacemaker защищает от сбоев по питанию на текущем мастере или на реплике; от сбоев процесса PostgreSQL по причине нехватки памяти, при недостатке файловых дескрипторов, превышении максимального числа открытых файлов; от потери сетевой связности с каким-либо из узлов в случае выхода из строя сетевой карты либо порта коммутатора.

Уровни Corosync&Pacemaker

Архитектура Corosync&Pacemaker предусматривает три уровня (см. рисунок):

  • кластеронезависимый: здесь располагаются ресурсы кластера (IP-адрес; сервис, запускаемый в операционной системе; блочное устройство; файловая система и пр.), агенты «фенсинга» сбойного узла (fencing — «ограждение») и др;
  • информационный (corosync): обеспечение сетевого взаимодействия узлов и обмен информацией о полноте кластера (наличии кворума) и т. д.;
  • управляющий (pacemaker): обработка событий, происходящих в кластере (отказ или присоединение узлов, ресурсов, переход узлов в сервисный режим и др.).

Pacemaker — мозг и менеджер ресурсов кластера (скриптов на любом языке, обычно на bash), отвечающий за доступность ресурсов и их защиту от сбоев. Pacemaker реагирует на события, происходящие в кластере, и выполняет определенные действия: остановку, запуск, перенос ресурсов и др. Узлы кластера — это физические серверы или виртуальные машины с установленным программным обеспечением Corosync&Pacemaker. Узлы, предназначенные для предоставления одинаковых сервисов, должны иметь одинаковую конфигурацию ПО, одинаковые конфигурационные файлы, пути установки PostgreSQL и идентичные версии СУБД.

Ресурсы кластера — скрипты на bash, Perl, Python, Cи или PHP, управляющие сервисами (и не только) в ОС, выполняющие такие действия, как start, stop, monitor, и поддерживающие обмен метаинформацией между узлами кластера. Для каждого сервиса в скрипт включаются свои специфические команды: например, для кластера PostgreSQL — конкретные именно для этой СУБД команды (promote, demote и др.). Ресурсы имеют множество атрибутов, которые хранятся в конфигурационном XML-файле Pacemaker. Разберем лишь наиболее интересные, позволяющие понять особенности настройки отказоустойчивого кластера на СУБД PostgreSQL.

Атрибут resource-stickiness — «липкость» ресурса (по умолчанию 0) — определяет место размещения ресурса в случае сбоя. Например, после выхода узла из строя его ресурсы переходят на другие узлы (стартуют на других узлах), а после восстановления узла могут вернуться к нему либо нет. Значение 0 указывает на то, что Pacemaker сам «решает», как размещать ресурсы, что не всегда может совпадать с точкой зрения администратора. Например, в случае, когда в отказоустойчивом кластере узлы имеют разную производительность, администратор выберет в качестве основного узел с большей производительностью. Кроме того, Pacemaker позволяет задавать разную липкость ресурса в зависимости от времени суток и дня недели.

Атрибут migration-threshold указывает количество отказов, по достижении которого Pacemaker решит, что узел далее непригоден для использования, и перенесет ресурсы с него на другой узел. По умолчанию этот параметр равен 0 — при любом количестве отказов автоматического переноса ресурсов не будет. С точки зрения отказоустойчивости следует выставить этот параметр отличным от 0 (например, 1). В таком случае при первом же сбое ресурс будет перемещен на другой узел.

Атрибут failure-timeout — количество секунд после сбоя, до истечения которых Pacemaker считает, что отказа еще не произошло, и ничего не предпринимает. По умолчанию значение равно 0.

Если несколько ресурсов должны запускаться в определенном порядке, останавливаться в обратном порядке и исполняться на одном узле, то они объединяются в группы. Все ресурсы одной группы будут последовательно запускаться на одном узле согласно порядку в группе. Например, ресурс pgsql (PostgreSQL) и ресурс IPaddr2 (виртуальный IP-адрес) логично объединить в группу. В таком случае Pacemaker сначала запустит сервис PostgreSQL, далее (при успешном запуске) запустит ресурс «виртуальный IP-адрес». При сбое хотя бы одного из ресурсов группы вся группа переместится на резервный узел.

В случае сбоя на основном узле с PostgreSQL ресурсы автоматически «перемещаются» на другой узел без нарушения работы приложений: на аварийном узле ресурсы PostgreSQL останавливаются и запускаются на резервном. В некоторых случаях потребуется фенсинг сбойного узла.

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

Для правильного функционирования отказоустойчивого кластера необходимы:

  • синхронизация времени между узлами в кластере;
  • разрешение имен узлов в кластере;
  • стабильность сетевых подключений в кластере;
  • наличие у узлов кластера функции управления питанием/перезагрузкой для организации «фенсинга»;
  • разрешение прохождения трафика по протоколам и портам.

Синхронизация времени требуется, чтобы все узлы жили по одному времени, что обычно реализуется путем установки сервера времени в локальной сети кластера. Разрешение имен реализуется путем установки в локальной сети сервера DNS либо внесения на всех узлах кластера локальной записи с именами и IP-адресами хостов (файл /etc/hosts). Стабильность сетевых соединений требуется для исключения ложных срабатываний. Например, если имеется нестабильная локальная сеть, в которой каждые несколько секунд происходит потеря соединения между узлами кластера и коммутатором, то Pacemaker будет считать сбоем пропадание связи более чем на 5 секунд, а это означает, что запустится механизм «перемещения» ресурсов на резервный узел. Далее после восстановления соединения Pacemaker будет уже считать узел «сбойнувшим», а при следующей потере связи «переместит» ресурсы на следующий резервный узел и так далее, пока не закончатся все узлы, что приведет к отказу всего кластера.

Наличие у узлов кластера функции управления питанием/перезагрузкой необходимо для того, чтобы при сбое узла изолировать его от остальных узлов кластера, таким образом исключив появление одновременно двух узлов, выполняющих роль мастера СУБД PostgreSQL. Для кластера из физических серверов эта функция реализуется специальной платой управления питанием (IPMI или ILO). Для виртуальных машин эту функцию реализует гипервизор, однако не все популярные гипервизоры умеют работать с Pacemaker.

Разрешение прохождения трафика по протоколам и портам — важное требование, так как в различных организациях службы безопасности часто устанавливают ограничения на прохождение трафика между подсетями или ограничения на уровне коммутаторов.

Corosync&Pacemaker работает как на физических серверах, так и в виртуальных средах KVM, VMware и VirtualBox, однако при использовании СУБД в виртуальных машинах для построения отказоустойчивых кластеров следует учитывать, что разные гипервизоры по-разному реализуют кеширование дисковых операций, не обеспечивая иногда своевременного сброса данных из кеша в систему хранения. Кроме того, для корректного функционирования запущенного в ОС виртуальной машины процесса corosync (входит в состав ПО Pacemaker&Corosync), отвечающего за обнаружение сбоев, требуется, чтобы ОС гарантированно планировала его исполнение на процессоре с приоритетом realtime.

***

Конфигурировать и обслуживать отказоустойчивый кластер на базе Corosync&Pacemaker достаточно просто: бинарные пакеты включены в состав многих ОС, а исходные файлы доступны на github.com, однако программе Corosync&Pacemaker требуется определенное время для обнаружения сбоя и «перемещения» ресурсов на резервный узел. Этого недостатка лишены коммерческие дистрибутивы СУБД PostgreSQL, имеющие такие модули как multimaster от Postgres Professional или Postgres-BDR от компании 2ndQuadrant, обеспечивающие работу в режиме, при котором все узлы кластера являются мастерами и содержат полные копии друг друга — при сбое какого-либо узла запросы от клиентов без задержек перенаправляются на другой «живой» узел.

Игорь Косенков (i.kosenkov@postgrespro.ru), Игорь Левшин (i.levshin@postgrespro.ru) — сотрудники, компания Postgres Professional (Москва).