Postres HA, две площадки, разные IP сети

Возвращаясь к напечатанному, а вот что если у нас две площадки, да еще и с разными IP подсетями? Например, так:

Clipboard01

Нам по-прежнему нужна та же самая active/passive конфигурация, только доступная клиентам на обеих площадках, в том числе и в случае полной потери одной из площадок.

Если наш софт не умеет работать с несколькими адресами сервера dbms (основной-резервный), то проще всего воспользоваться балансировщиком нагрузки, типа HAproxy. Но при этом HAproxy должен как то узнать, где находится мастер. Вариант, который сразу приходит в голову — привязать IP к мастеру средствами кластера.

Clipboard02

IP1 — из сети первого сайта, IP2 — из сети второго сайта. Понятно, что когда мастер (A) находится на первой площадке, активен только IP1. IP2 не может «подняться». В случае аварии мастер переезжает на сайт 2, поднимается IP2 и Load Balancing перестраивается на него.

Есть одна проблема: конфигурация с failover cluster-ом, описанная в статье «Высокодоступный Postgres. Кластер Active/Standby со stream-репликацией между узлами.» не будет работать с разными IP сетями. Дело в ресурсном агенте pgsql RA  для pacemaker: он не умеет работать с двумя IP адресами, только с одним. Перепиливать код агента — не вариант, поэтому ищем дальше. И находим … Governor.

Clipboard03

В первом приближении схема работы достаточно простая:

  1. Сервер стартует, проверяет через etcd (распределенная база типа ключ-значение) наличие postgres-мастера
  2. Если мастера нет, то сервер становится мастером, захватывает ключ в etcd и периодически его обновляет. Если ключ не обновлять, через некоторое время (30 сек) он удаляется из базы;
  3. Если мастер есть, то сервер настраивает потоковую репликацию с мастера и периодически  проверяет ключ в etcd. Если ключ исчезает, это означает, что мастер вышел из строя и  серверы начинают гонки за право захвата ключа в etcd. Тот, кому это удается первому, переходит в режим мастера, прочие настраивают потоковую репликацию с нового мастера.

В целом, конечно же,  все чуть более сложно.

В случае выхода из строя мастер-сервера происходит failover:

Clipboard04

Я чуть поправил governer кувалдой, на предмет корректного заполнения файла pg_hba.conf. Исправленная версия - здесь.

Инструкция по эксплуатации:):

Подготовка к установке

1. Установить CentOS 7

2. Обновить дистрибутив:
# yum update
и перезагрузить после обновления:
# reboot

3. Отключить SELinux и firewalld:
# setenforce 0
и в файле /etc/selinux/config
SELINUX=enforcing заменить на SELINUX=disabled

# systemctl stop firew disable firewalld

5. Удостовериться, что установлен верный часовой пояс:
# date
Sat Apr 18 08:41:57 PDT 2015
И, при необходимости, поправить:
# rm -f /etc/localtime
# ln -s /usr/share/zoneinfo/Europe/Moscow /etc/localtime
# date
Sat Apr 18 18:44:15 MSK 2015

4.Рекомендуется
В файле /etc/host прописать IP адрес и имя, как минимум, локальной машины, что то типа

192.168.0.109 pg01 db01.test.local

установить, настроить (вписать в случае необходимости локальные серверы времени в файл /etc/ntp.conf) и запустить сервис ntpd:

# yum install ntp ntpdate
# systemctl enable ntpd
# systemctl start ntpd

Установка:

# yum install etcd

Настроить etcd глядя в инструкцию https://github.com/coreos/etcd/blob/master/Documentation/runtime-configuration.md#restart-cluster-from-majority-failure
Нам нужна трехузловая конфигурация с  узлом-свидетелем на третьей площадке.
1. Проинициализировать первый сервер
2. Добавить к нему второй и третий

# yum localinstall http://yum.postgresql.org/9.4/redhat/rhel-7-x86_64/pgdg-centos94-9.4-1.noarch.rpm
# yum install postgresql94 postgresql94-server postgresql94-contrib postgresql94-libs postgresql94-plpython uuid pgadmin3_94 python PyYAML python-psycopg2

Скопировать файлы из архива в /home/governor
Создать лог файлы:
# touch /var/log/governor.log; chown postgres.postgres /var/log/governor.log
# touch /var/log/haproxy_status.log; chown postgres.postgres /var/log/haproxy_status.log

Поредактировать файл конфигурации postgres0.yml (не забываем изменить ИМЯ сервера в секции «postgresql:», каждый сервер должен в качестве источника данных о конфигурации использовать локальную службу etcd)

Запуск:

# /home/governor/governor.run
либо скопировав ha-proxy_status.service и governor.service в /etc/systemd/system/
и сказав

# systemctl daemon-reload
через
# systemctl start governor.service
# systemctl start ha-proxy_status.service

Чтобы стартовал автоматически при загрузке системы:
# systemctl enable governor.service
# systemctl enable ha-proxy_status.service

Перед настройкой брокеров необходимо установить пароль пользователя postgres в psql:
# PWD=’P@$$w0rd!’; sudo -u postgres psql -c «ALTER USER postgres WITH PASSWORD ‘$PWD'»

Мониторинг:

# etcdctl -C 192.168.91.76:2379 -o extended get /service/gp-demo/leader — сообщить кто является мастер-сервером
# etcdctl -C 192.168.91.76:2379 cluster-health — состояние кластера etcd
# etcdctl -C 192.168.91.76:2379 member list — список member-серверов кластера etcd
# etcdctl -C 192.168.91.76:2379 -o extended ls /service/gp-demo/members -список серверов postgres в конфигурации

Лог-файлы:

# tail -f /var/lib/pgsql/9.4/data/pg_log/postgresql-<день недели>.log
# tail -f /var/log/governor.log
# tail -f /var/log/haproxy_status.log
# tail -f /var/log/messages

Дальше нужно решить еще одну проблему: после того, как произошел failover а старый мастер остался цел, есть задача запустить его в режиме slave, чтобы он принимал потоковую репликацию с нового мастера. И тут мы видим, что потоковая репликация не настраивается, а лог-файле postgres что то типа:

< 2015-11-19 22:32:08.963 MSK >FATAL: requested timeline 29 is not a child of this server’s history
< 2015-11-19 22:32:08.963 MSK >DETAIL: Latest checkpoint is at 4/AA000028 on timeline 28, but in the history of the requested timeline, the server forked off from that timeline at 4/A90071A8.
< 2015-11-19 22:32:08.966 MSK >LOG: startup process (PID 4281) exited with exit code 1
< 2015-11-19 22:32:08.966 MSK >LOG: aborting startup due to startup process failure

Для того, чтобы это исправить у нас есть два пути:

(неправильный, но работающий) Очищать датакаталог слейва
1. Выбрать сервер, который будет мастером. Сделать его мастером, если он еще не мастер (остановить оба сервера, затем запустить новый мастер)
2. Очистить и перезапустить slave:
# systemctl stop governor.service
# rm -rf /var/lib/pgsql/9.4/data/
# systemctl start governor.service

Это работает, но это не очень правильный путь (что если размер базы 10ГБ?  После такого перезапуска она будет репликаться с нового мастера на новый slave весьма долго. И все это время наша конфигурация будет незащищенной).

Правильный способ — настройка архива логов postgres, доступного всем серверам. Например, на NFS share сервера-свидетеля (witness). Для этого нужно сделать следующее:

Разместить архив на witness узле, экспортировать через nfs
# cat /etc/exports
/wal_archive 192.168.0.0/16(rw,no_root_squash)

Примонтировать экспортированный каталог на каждом узле postgres:
# cat /etc/fstab

192.168.91.76:/wal_archive /var/lib/pgsql/9.4/wal_archive nfs defaults 0 0
Добавить в postgres0.yml:

recovery_conf:
   restore_command: cp /var/lib/pgsql/9.4/wal_archive/%f %p
   archive_cleanup_command: pg_archivecleanup /var/lib/pgsql/9.4/wal_archive %r
parameters:

archive_command: cp %p /var/lib/pgsql/9.4/wal_archive/%f
Ограничения вышеописанной конфигурации:

  1. Минимальное кол-во узлов кластера с установленным etcd — три. Минимальное кол-во живых узлов, при которых система еще работает (и failover может успешно случиться) — два.
  2.  Witness должен стартовать перед серверами db и к моменту их старта уже экспортировать NFS папку с лог-файлами.
Реклама

One thought on “Postres HA, две площадки, разные IP сети

  1. Уведомление: PostgreSQL — репликация, ссылки | Pilat66 blog

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход /  Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход /  Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход /  Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход /  Изменить )

Connecting to %s