Pgpool что это
Перейти к содержимому

Pgpool что это

PostgreSQL 9.3 + Pgpool-II

Решил поделиться с вами опытом настройки кластера PostgreSQL 9.3, состоящего из двух нод, управлением которого занимается pgpool-II, без использования Stream Replication (WAL). Надеюсь, кому-нибудь будет интересно.

image

Как Вы понимаете, это будут два отдельно стоящих сервера, которыми будет управлять pgpool-II.

  • 4vCPU;
  • 16 Гб памяти;
  • CentOS 6.5;
  • 50 Гб — система;
  • 100 Гб — pg_xlog
  • 500 Гб — каталог с данными
  • 4vCPU;
  • 8 Гб памяти;
  • CentOS 6.5;
  • 50 Гб — система;

Про установку PostgreSQL в детали вдаваться не буду, так как она стандартная.

Настройка pgpool-II.
За основу настройки pgpool-II, взял инструкцию с официального сайта: www.pgpool.net/pgpool-web/contrib_docs/simple_sr_setting2_3.3/index.html

Хотел бы обратить внимание только самые важные моменты:

После настройки конфигурационного файла, запускаем службу pgpool. Можно также настроить pgpooladmin для мониторинга состояния нод.

Также статус нод с PostgreSQL можно посмотреть, выполнив команду на pgpool:

Далее, проверяем работу нашей схемы — создаем пустую БД через pgpool. Сделать это можно двумя способами:
1) через pgadmin, подключившись к IP-адресу pgpool-II;
2) выполнив команду на ноде с pgpool: createdb -p 9999 bench_replication

Репликация и балансировка нагрузки базы данных¶

Репликация это механизм синхронизации содержимого нескольких копий базы данных. Это может быть использовано для обеспечения резервного копирования и отказоустойчивости. При падении одной СУБД ее запросы будет обслуживать другая копия.

Балансировка нагрузки заключается в распределнии запросов от пользователей по разным копиям базы данных. Это позволяет выполнять большее количество запросов одновременно.

Для обеспечения задачи репликации и балансировки нагрузки базы данных развернем кластер master-slave на СУБД PostgreSQL. Кластер должен содержать один ведущий сервер (Master), один ведомый (Slave) и один узел масштабирования (Balancer).

Для балансировки нагрузки будет использоваться ПО Pgpool-II. Данное ПО также будет использоваться для обеспечения отказоустойчивости (failover, online recovery).

Примерная схема решения представлена на ngw_admin_replcation_pic .

docs_ngweb/source/_static/ngw_replica.png

Схема репликации и балансировки нагрузки. ¶

Реализация решения будет описана на примере СУБД PostgreSQL 9.5 и ПО Pgpool-II в ОС Ubuntu 16.04.

Подготовка среды¶

Создадим 3 виртуальные машины (ОС Ubuntu 16.04 LTS):

pgpool (IP адрес 192.168.250.181)

pgmaster (IP адрес 192.168.250.182)

pgslave (IP адрес 192.168.250.183)

На виртуальных машинах pgmaster и pgslave установим СУБД PostgreSQL с модулем расширения PostGIS и дополнительным ПО Pgpool-II:

На виртуальной машине pgpool установим ПО Pgpool-II:

Настройка потоковой репликации¶

Отредактируйте конфигурационный файл postgresql.conf на виртуальной машине pgmaster следующим образом:

В файле должны быть следующие строки:

Строка с комментарием обязательна и нужна для переключения master-slave . Параметры конфигурационного файла имеют следующие значения:

  • wal_level = hot_standby — сервер начнет писать в WAL логи так же как и при режиме «archive», добавляя информацию, необходимуюдля восстановления транзакции

  • max_wal_senders = 2 — максимальное количество слейвов

  • wal_keep_segments = 32 — минимальное количество файлов c WAL сегментами в pg_xlog директории

Далее добавим строчку для репликации в файл pg_hba.conf :

В файле должны быть следующие строки:

Это разрешит доступ к СУБД для нужд репликации из подсети 192.168.250.х.

Перезапустим СУБД на виртуальной машине pgmaster:

Останавливаем СУБД на виртуальной машине pgslave:

Отредактируйте конфигурационный файл postgresql.conf на виртуальной машине pgslave следующим образом:

В файле должны быть следующие строки:

Далее добавим строчку для репликации в файл pg_hba.conf :

В файле должны быть следующие строки:

На виртуальной машине pgmaster под пользователем postgres создаем резервную копию кластера базы данных и пересылаем на виртуальну машину pgslave.

Для передачи данных при помощи утилиты rsync ее необходимо установить, а также обеспечить временный доступ к виртуальной машине pgslave пользователю root по ssh.

На виртуальной машине pgslave создаем конфигурационный файл репликации /var/lib/postgresql/9.5/main/recovery.conf :

Параметр trigger_file отвечает за путь, по которому PostgreSQL ищет файл, чтобы переключиться в режим ведущего. В данном случае файл ищется в папке с конфигурацией СУБД (/var/lib/postgresql/9.5/main/failover).

Дадим права на новый файл:

Запустим СУБД на виртуальной машине pgslave:

Проверим активность репликации на виртуальной машине pgmaster:

Проверим активность репликации на виртуальной машине pgslave:

Настройка узла масштабирования¶

Изменим конфигурационный файл /etc/pgpool2/pgpool.conf :

Изменим конфигурационный файл /etc/pgpool2/pool_hba.conf :

Добавим пароли в файл /etc/pgpool2/pool_passwd :

Проверим работоспособность pgpool:

Настройка автоматического failover¶

Автоматический failover предназначен для переключения одного из ведомых серверов СУБД в роль мастера при падении сервера с мастером. Это необходимо для обеспечения возможности выполнения запросов на запись.

Failover требует настройки удаленного соединения по протоколу ssh без пароля. Для этого нужно создать ssh-ключи пользователя postgres и разослать их на виртуальные машины pgmaster и pgslave.

Для начала назначим пароль для пользователя postgres на виртуальных машинах pgmaster и pgslave. Для этого выполним:

Далее на вирутальной машине pgpool выполним следующую команду (пароль оставим пустым):

Перешлем ключ на виртуальные машины pgmaster и pgslave:

Добавим в конфигурационный файл /etc/pgpool2/pgpool.conf следующую строчку:

Создадим скрипт /etc/pgpool2/failover.sh следующего сожержания:

Назначим ему права на исполнение:

Протестировать механизм автоматического failover можно следующим образом:

Отключить ведущий сервер

Выполнить запрос show pool_nodes; на узле масштабирования

Смотреть логи pgpool на предмет выполнения скрипта

Убедиться в том, что ведомый сервер после выполнения скрипта может принимать запросы на запись

Для тестирования механизма автоматического failover остановим СУБД Postgres на виртуальной машине pgmaster:

Из листинга видно, что старый master имеет статус 3 , а старый slave стал новым мастером.

Добавим старый мастер в качестве slave. Для этого на виртуальной машине pgmaster:

Создадим конфигурационный файл репликации /var/lib/postgresql/9.5/main/recovery.conf :

Дадим права на новый файл:

Исправим конфигурационный файл postgresql.conf следующим образом:

В файле должны быть следующие строки:

3. На виртуальной машине pgslave под пользователем postgres создаем резервную копию кластера базы данных и пересылаем на виртуальну машину pgmaster.

На виртуальной машине pgmaster запустим СУБД:

На виртуальной машине pgpool перезапустим сервис:

Используемые источники¶

При реализаци механизма репликации и балансировки нагрузки использовались следующие источники:

Записки угрюмого поднимателя пингвинов.

Небольшая хаутушечка по настройке pgpool-кластера с steaming replication postgres.

1. Подготовка посгреса.

Необходимо настроить потоковую репликацию.
Первым делом необходимо настроить авторизацию юзера postgres на машинах кластера по ssh-ключам без пароля (причем, не забыть про коннект по ssh к самому себе). ssh-keygen и ssh-copy-id в помощь.

Конфиг postgresql.conf лучше иметь одинаковый (за исключением директивы archive_command), что на мастере, что на слейве — так удобнее и проще, тоже самое касается каталогов с базой и архивлогами.

hot_standby = on // указывает что слейв будет в одноименном режиме, т.е. с него возможны селекты; на мастере она игнорируется
wal_level = hot_standby // директива для мастера, указывает режим репликации; на слейве игнорируется
max_wal_senders = 4 // число процессов репликации, должно быть не меньше числа слейвов
wal_keep_segments = 12 // сколько хранить wal-логов, если число будет слишком маленьким — слейв не сможет засинхронизироваться после длительного оффлайна
archive_mode = on // дополнение к потоковой репликации, ускоряет синхронизацию после длительного оффлайна
archive_command = ‘rsync -aq %p <slave-name>:/somedir/archive/%f’ // команда для отправки файликов архив-логов. единственный параметр, который будет различаться на мастере и слейве (мастер указывает на слейв, слейв на мастер)

Кроме того, listen_address не должен быть localhost, иначе слейв не сможет подключиться (извращения со слейвом на том же хосте опустим), а так же необходимо настроить pg_hba.conf для разрешения подключения replication-юзера, что-то вроде такого:

host replication postgres 192.168.1.0/24 trust

После этого запускаем мастер-сервер. Готовим слейв.
Проще всего сделать pg_basebackup с работающего мастера, указать в archive_command хостнейм мастера и добавить файлик recovery.conf:

standby_mode=’on’
primary_conninfo=’host=master port=5432 user=postgres’ // реквизиты подключения к мастеру
trigger_file=’/somedir/trigger_file’ // путь до триггер-файла. при его появлении посгрес будет считать что мастер сдох и нужно самому становиться мастером
restore_command=’cp /somedir/archive/%f %p’ // команда для применения архивлогов
archive_cleanup_command=’/usr/pgsql-9.2/bin/pg_archivecleanup /somedir/archive %r’ // очистка примененных архивлогов

После этого можно можно запускать слейва, он должен успешно подключиться к мастеру и войти в режим hot_standby.

2. Настройка pgpool

Поставить pgpool под rhel/centos можно из пакетов, так что про традиционное для подобных хаутушечек configure&&make&&make install можно забыть.
Правим pgpool.conf:

backend_hostname0 = ‘hostname’
backend_port0 = 5432
backend_weight0 = 1
backend_data_directory0 = ‘/opt/pgsql/9.2/data’
backend_flag0 = ‘ALLOW_TO_FAILOVER’

Такими директивами (с увеличением порядкового номера) описываются все ноды кластера.
Включаем авторизацию через pgpool:

enable_pool_hba = on
authentication_timeout = 60
pool_passwd = ‘pool_passwd’ #имя файлика с юзерами/паролями в каталоге /etc/pgpool-II

Для авторизации по паролям через pgpool необходимо чтобы юзер и пароль совпадали, что в pgpool-е, что в посгресе, тип авторизации в посгресе должен быть md5. Например, создаем юзера «root» с паролем «qwerty»:

createuser -lP root

в pg_hba.conf добавляем

host all root pgpool-host-ip md5
pg_md5 -u root -p

вывод добавляем в pool_passwd, права на файл должны позволять юзеру postgres его прочитать.

Возвращаемся к pgpool.conf:

load_balance_mode = on # включаем балансировку нагрузки — селекты смогут выполняться в т.ч. на слейве

master_slave_mode = on
master_slave_sub_mode = ‘stream’ # включаем streaming replication

sr_check_period = 10 # период проверки репликации
sr_check_user = ‘root’ # реквизиты для проверки репликации
sr_check_password = ‘qwerty’

health_check_period = 5 # проверка доступности нод
health_check_timeout = 10
health_check_user = ‘root’ # реквизиты для проверки
health_check_password = ‘qwerty’

failover_command = ‘/opt/pgsql/failover.sh %d %P %H %R’ # самое важное — команда для файловера, будет исполняться при падении какой-либо из нод

Скрипт файловера довольно простой: если упал слейв — не делать ничего, если мастер — создать триггер-файл на слейве. А чтобы все это получилось — ssh-ключики и создавались.

#!/bin/bash
failed_id=$1
old_primary_id=$2
new_master_host_name=$3
new_database_path=$4
trigger=trigger_file

if [ $failed_id = $old_primary_id ];then # master failed
ssh $new_master_host_name touch $new_database_path/$trigger # let standby take over
fi

На этом минимум — закончен. pgpool сможет обслуживать соединения, отслеживать состояния нод и промоутить слейва в случае падения мастера.
Остается решить вопрос с рекавери — восстановлением работы упавшей ноды. Для этого есть 2 варианта:

восстанавливать ноду ручками (т.е. без участия pgpool-а) и давать pgpool-у команду на присоединение ноды

настроить online-recovery в pgpool-е, но все равно восстанавливать ручками 😀 хотя бы потому, что команду на восстановление придется все же давать руками (через консоль или модный pgpoolAdmin)

Первый вариант довольно прост и по-сути полностью повторяет официальный посгресовый гайд: сделать бейсбэкап с работающего мастера, создать recovery.conf и запустить ноду как слейв. Это все можно оформить в удобный скрипт:

cluster_master=$1
recovery_host=$2
recovery_dir=$3

psql -h $cluster_master -c «SELECT pg_start_backup(‘Streaming Replication’, true)» postgres

rsync -C -a -c —delete —exclude postgresql.conf —exclude postmaster.pid \
—exclude postmaster.opts —exclude pg_log \
—exclude recovery.conf —exclude recovery.done \
—exclude pg_xlog \
$recovery_dir/ $recovery_host:$recovery_dir/
psql -h $cluster_master -c «SELECT pg_stop_backup()» postgres

ssh $recovery_host «mkdir $recovery_dir/pg_xlog; chmod 700 $recovery_dir/pg_xlog»
rec=`mktemp`
cat > $rec << EOF
standby_mode=’on’
primary_conninfo=’host=$cluster_master port=5432 user=postgres’
trigger_file=’$recovery_dir/trigger_file’
restore_command=’cp /opt/pgsql/archive/%f %p’
archive_cleanup_command=’/usr/pgsql-9.2/bin/pg_archivecleanup /opt/pgsql/archive %r’
EOF
scp $rec $recovery_host:$recovery_dir/recovery.conf
rm -f $rec

ssh $recovery_host sed -i «s/slave-hostname/$cluster_master/g» $recovery_dir/postgresql.conf

Соответственно алгоритм восстановления по этому варианту таков:

Запустить скрипт с работающего мастера, указать хостнеймы мастера, восстанавливаемого слейва и каталог pg_data. Он подготовит слейв

Запустить слейв. Если нигде ничего не напутано — он успешно подключится к мастеру и начнет работать хот-стендбаем.

Дать команду пгпулу на присоединение ноды: pcp_attach_node timeout hostname port# username password nodeID. nodeID восстанавливаемой ноды можно увидеть из вывода pcp_pool_status.
После этого нода будет вновь доступна в пгпуле.

Второй вариант — online-recovery в pgpool.

Механизм работы пгпула в этом варианте несколько неочевиден. В отличие от fileover и прочих функций — рекавери запускается не напрямую скриптом, а через вызов посгресовых функций pgpool_recovery и pgpool_remote_start, которые уже вызывают непосредственные скрипты (нафига такой изврат. ). Соответственно, чтобы все это работало — в посгрес должны быть загружены эти функции (в базу postgres и template), а для загрузки этих функций необходима шаред-библиотека под посгрес pgpool-recovery.so.

После добавления пгпуловских фукнций в посгрес нужно создать 2 скрипта в каталоге $pg_data: pgpool_remote_start (именно с таким названием!) и recover-online (тут уже название произвольное).

Первый скрипт, как видно из названия — скрипт удаленного запуска посгреса. Я предлагаю юзать системные инит-скрипты и судо, скрипт такого вида:

if [ $# -ne 2 ]
then
echo «pgpool_remote_start remote_host remote_datadir»
exit 1
fi

DEST=$1
DESTDIR=$2
PGCTL=/usr/pgsql-9.2/bin/pg_ctl

ssh -T $DEST «sudo service postgresql-9.2 start»
Естественно, для его работы в судоерс необходимо разрешить юзеру посгрес выполнять «service postgresql-9.2 start» без запроса пароля.
Второй скрипт — собственно процедура рекавери. Скрипт такой:
#!/bin/bash

if [ $2 = «slave.hostname» ]
then
cluster_master=»master.hostname»
else
cluster_master=»slave.hostname»
fi

psql -c «SELECT pg_start_backup(‘Streaming Replication’, true)» postgres

rsync -C -a -c —delete —exclude postmaster.pid \
—exclude postmaster.opts —exclude pg_log \
—exclude recovery.conf —exclude recovery.done \
$recovery_dir/ $recovery_host:$recovery_dir/
psql -c «SELECT pg_stop_backup()» postgres

rec=`mktemp`
cat > $rec << EOF
standby_mode=’on’
primary_conninfo=’host=$cluster_master port=5432 user=postgres’
trigger_file=’$recovery_dir/trigger_file’
restore_command=’cp /opt/pgsql/archive/%f %p’
archive_cleanup_command=’/usr/pgsql-9.2/bin/pg_archivecleanup /opt/pgsql/archive/%r’
EOF
scp $rec $recovery_host:$recovery_dir/recovery.conf
rm -f $rec

ssh -T $recovery_host sed -i «s/hostname/$cluster_master/g» $recovery_dir/postgresql.conf

Скрипт похож на «ручной» скрипт рекавери, но слегка изменен, т.к. приходится определять хостнейм текущего мастера (функция pgpool_recovery не передает имя мастера).
Когда все скрипты на месте, функции в базу загружены — можно переходить к конфигу пгпула.

Править нужно раздел «online recovery»:

recovery_user = ‘postgres’ # юзер (посгресовый)
recovery_password = ‘pass’ # пароль
recovery_1st_stage_command = ‘recover-online.sh’ # имя рекавери-скрипта

Остальные параметры можно не трогать. Перезапускаем пгпул и можно пробовать — механизм должен работать.
Тут и подходим к самому главному — нафига было столько геморроя? Ибо пгпул не будет пытаться самостоятельно восстанавливать ноду после падения — он будет терпиливо ждать команды pcp_recovery_node (или нажатия кнопки в pgpool-admin-е) и только после получения ее с нужными параметрами соизволит восстановить ноду.
А раз ручками лезть все равно надо — по-моему проще «ручным» скриптом восстановить ноду и жмакнуть pcp_attach_node.

3. Устраняем единую точку отказа.

Pgpool в единственном числе — общая точка отказа. Для устранения этой проблемы — необходим еще один (или более) пгпул и настроенный watchdog. В случае с 2-мя хостами посгреса, master/slave — очевидным вариантом будет установка пгпула на каждый из хостов.
Конфиги пгпула должны быть одинаковые (включая скрипты файловера, рекавери и т.п.), различия есть только в разделе watchdog в параметрах.

use_watchdog = on #включаем вотчдог
trusted_servers = ‘192.168.222.2’ #лучше указать один/несколько гарантированно доступных хостов — для исключения split-brain ситуации
wd_hostname = ‘hostname’ # имя хоста, на котором этот пгпул запущен; свое для каждого хоста
wd_port = 9000 # порт должен быть открыт на фаерволле
wd_authkey = ‘qwerty’ # ключик авторизации вотчдога, должен быть одинаковый. можно вообще без него
delegate_IP = ‘192.168.222.220’ # виртуальный айпи, по которому будет доступен кластер. именно на него нужно натравливать приложение, желающее соединиться с базой
wd_lifecheck_method = ‘heartbeat’ #метод работы вотчдога, heartbeat появился с версии 3.3. query у меня не заработал (как и вотчдог в 3.2 вообще)
wd_interval = 5
wd_heartbeat_port = 9694 #порт для хартбита. должен быть открыт в фаерволле
wd_heartbeat_keepalive = 2
wd_heartbeat_deadtime = 15
heartbeat_destination0 = ‘hostname2’ #имя другого хоста
heartbeat_destination_port0 = 9694
other_pgpool_hostname0 = ‘hostname2’ #имя другого хоста
other_pgpool_port0 = 5432
other_wd_port0 = 9000

Таким образом, конфиги различаются только параметрами wd_hostname, heartbeat_destination0 и other_pgpool_hostname0. Еще один важный момент — если пгпул запускается не от рута (а это так, если ставился из пакетов; да и вообще — нефиг), то для поднятия/опускания сетевых алиасов необходимо поставить suid-бит на /sbin/ifconfig и /usr/sbin/arping.
Если не ошиблись с хостнеймами и портами, то при запуске пулов они друг-друга увидят, один станет мастером и поднимет алиас, другой будет в стендбае, на случай падения мастера.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *