"Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор...

18
Strictly Confidential Strictly Confidential Отказоустойчивый standby PostgreSQL: HAProxy + PgBouncer Victor Yagofarov [email protected]

Transcript of "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор...

Page 1: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential

Отказоустойчивый standby PostgreSQL: HAProxy + PgBouncer

Victor Yagofarov [email protected]

Page 2: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 2

Обо мне

Виктор Ягофаров, Avito.ru

• Администратор Баз Данных• 8 лет в качестве Системного Администратора FreeBSD и Linux

• 2 года занимался развитием PostgreSQL-инфраструктуры в Rambler

• Тем же занят в Avito :)

Page 3: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 3

О чем доклад?

• Как мы резервируем postgres в Avito• Почему именно так, другие варианты• Протокол pgsql и haproxy + pgbouncer• Подводные камни• Tips and tricks

Page 4: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 4

PgBouncer

• Мультиплексор: "многие к одному"• transaction pooling для приложений (более экономный)

• session pooling для разработчиков (тяжелее сломать)

• Возможность совмещать разные виды пулов в 1.6• pg_hba.conf -style конфиг, начиная с 1.7

Page 5: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 5

HAProxy

• Быстрый tcp/http load balancer• Гибкость настройки способов балансировки для разных типов нагрузки

• Тонкий тюнинг failover• Custom http health checks: логика проверок ограничена лишь фантазией

• Настраиваемое поведение при переключении на backup и обратно

• Возможность с помощью health checks на множестве нод агрегировать статистику и видеть картину в целом

Page 6: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 6

app01

PgBouncer

application

HAProxy

Standby01

PgBouncer

PostgreSQ

Standby02

PgBouncer

PostgreSQ

Standby03

PgBouncer

PostgreSQ

app101

PgBouncer

application

HAProxy

Active Backup Failed

Общая схема

Page 7: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 7

Конфиг HAProxy и PgBouncerlisten pgsql-db_main_s

bind 127.0.0.1:16002timeout client 20mtimeout connect 1stimeout server 20mbalance roundrobinoption log-health-checksoption tcpkaoption tcplogoption httpchk GET /db_main_s?username=app_ro&port=6432 # настройки чекераhttp-check send-state

server host-sb01 host-sb01:6432 check addr 127.0.0.1 port 5777 inter 6s fall 5 rise 3server host-sb02 host-sb02:6432 check addr 127.0.0.1 port 5777 inter 6s fall 5 rise 3

backupserver host-sb03 host-sb03:6432 check addr 127.0.0.1 port 5777 inter 6s fall 5 rise 3

backup[databases]db_main_s = host=127.0.0.1 port=16002 pool_size=10

Page 8: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 8

Health checking

cat /etc/xinetd.d/pgcheck

service pgcheck{ disable = no type = UNLISTED flags = REUSE socket_type = stream port = 5777 wait = no user = nobody server = /usr/local/bin/pgcheck log_on_failure += USERID only_from = 127.0.0.1/32 per_source = UNLIMITED}

Page 9: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 9

pgcheck - эмулятор web-сервиса

#!/usr/bin/env perl…$| = 1; # отключаем буферизацию

# Set whole script timeout to 5 seconds via alarm$SIG{ ALRM } = sub { http 504 => "Timeout checking database health";};alarm 5; ### время таймаута всего скрипта…

my $dbh = DBI->connect("dbi:Pg:dbname=$db;host=$host;port=$port", "$username", '', { PrintError => 0, RaiseError => 0, pg_server_prepare => 0 } ) or # отключаем prepare чтобы избежать prepare на сервере http 502 => "Error occured connecting database ($DBI::errstr)";…

Page 10: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 10

pgcheck - эмулятор web-сервиса

… продолжение скрипта

# do not use database if check_ha() returns 'false'

my $sth = $dbh->prepare("select public.check_ha()");my $rv = $sth->execute or http 503 => "Error occured while 'select check_ha()' on '$db' at '$host' ($DBI::errstr)";my @row = $sth->fetchrow_array;if ( $row[0] == 0 ) { http 503 => "Error occured while 'select check_ha()' on '$db' at '$host': service disabled manually";}…# If everything is ok, return 200http 200 => "Database '$db' at '$host' is alive";

Page 11: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 11

check_ha()

db_main=# \df+ check_ha

use Sys::Hostname;my $h = Sys::Hostname::hostname;

if ($h eq 'unknown-host') { return 0;} elsif ($h eq 'db-sql02') { # standby return 1;} elsif ($h eq 'db-sql03') { # master return 0;} elsif ($h eq 'db-sql05') { # standby return 1;} else { return 0;}

Page 12: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 12

Поведение при разрывах tcp

select * from tbl where id = 1 select * from tbl where id = 1 # разрыв и переключение на другой сервер в haproxy .. select * from tbl where id = 1

Вне транзакции выполним, подключившись к серверу через локальный pgbouncer:

Последний запрос выполнится без ошибок!Но в случае транзакции, последний select получит ошибку

select 'text' || pg_sleep(60) ;

Клиент получит ошибку "ERROR: server conn crashed"

Долгий запрос:

Page 13: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 13

Поведение при разрывах tcp

• Не транзакционные, быстрые запросы в одной сессии (до 1 мс) могут не заметить разрыва tcp (tcpkill/tcpdrop), следовательно - они более "stateless" и имеют меньше шансов завершиться с ошибкой. Это же касается быстрых транзакций.

• Локальный pgbouncer пересоздает подключение незаметно для клиента, haproxy повышает HA.

• Но переключение в haproxy происходит не мгновенно

• HAProxy по-умолчанию не разрывает существующие сессии (см. on-marked-down shutdown-sessions, on-marked-up shutdown-backup-sessions)

Page 14: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 14

Особенности pgbouncer

• Проблема осиротевшего процесса в PostgreSQL• Pgbouncer cannot connect to server

Page 15: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 15

Особенности haproxy

• haproxy "релоадит" конфиг через порождение нового процесса и передачу в него новых коннектов. Старый процесс может ждать бесконечно старые tcp states

• в http статистике haproxy не всегда показывает переменную с описанием ошибки чекера

Page 16: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 16

Особенности psql

• Особенности флагов psql (-1, -f, -c)• set local statement_timeout и psql -c

psql -Upostgres -c "set local statement_timeout = '3 s'; select pg_sleep(5)"

psql -1 -Upostgres -h avi-sql26 -p 6432 -f- << 'EOF'set local statement_timeout = '3 s';select pg_sleep(5);EOF

Page 17: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential 17

Особенности psql

• psql -v ON_ERROR_STOP=1 : обязателен при -f• Что еще не работает в single-transaction (-1):

create index concurrently ;create database;vacuum;- - что-то еще? вполне!

• \timing включает в себя задержки сети• set search_path в transaction pooling - так делать опасно. Используйте set local в transaction pooling mode

Page 18: "Отказоустойчивый standby PostgreSQL (HAProxy + PgBouncer)" Виктор Ягофаров (Avito)

Strictly ConfidentialStrictly Confidential

Victor Yagofarov [email protected]

Всем спасибо!

Вопросы?