Масштабирование PostgreSQL: готовые решения от Skype

Автор: Иван Золотухин

Совсем недавно компания Skype выложила в открытое пользование под лицензией BSD ряд своих наработок, анонсированных прошлым летом на конференции, посвященной 10-летию PostgreSQL. Эти решения позволяют полностью решить проблемы масштабирования и резервирования OLTP систем, а также организовать необходимую синхронизацию с OLAP базами данных, решив таким образом 2 самых основных проблемы, с которыми сталкиваются разработчики баз данных при построении высоконагруженных систем. В пресс-релизы об этом событии вошли лишь краткие описания продуктов от Skype, поэтому возникла необходимость описать более подробно те возможности, которые появились у разработчиков и администраторов баз данных PostgreSQL.

 

PL/Proxy

PL/Proxy представляет собой прокси-язык для удаленного вызова процедур и партицирования данных между разными базами. Основная идея его использования заключается в том, что появляется возможность вызывать функции, расположенные в удаленных базах, а также свободно работать с кластером баз данных (например, вызвать функцию на всех узлах кластера, или на случайном узле, или на каком-то одном определенном).

Чем PL/Proxy может быть полезен? Он существенно упрощает горизонтальное масштабирование системы. Становится удобным разделять таблицу с пользователями, например, по первой латинской букве имени -- на 26 узлов. При этом приложение, которое работает непосредственно с прокси-базой, ничего не будет замечать: запрос на авторизацию, например, сам будет направлен прокси-сервером на нужный узел. То есть администратор баз данных может проводить масштабирование системы практически независимо от разработчиков приложения.

PL/Proxy позволяет полностью решить проблемы масштабирования OLTP систем. В систему легко вводится резервирование с failover-ом не только по узлам, но и по самим прокси-серверам, каждый из которых работает со всеми узлами.

Несколько примеров от Skype

1. Простейший пример удаленного вызова функции. Соединяемся с dbname=users выполняем запрос SELECT * FROM get_user_email($1); на удаленной базе:

CREATE FUNCTION get_user_email(username text)
RETURNS text AS $$
    CONNECT 'dbname=users';
$$ LANGUAGE plproxy;

2. Пример с партицированием. Пользователи разделены по разным базам, номер партиции вычисляется функцией hashtext(username):

CREATE FUNCTION get_user_email(username text)
RETURNS text AS $$
    CLUSTER 'userdb';
    RUN ON hashtext(username);
$$ LANGUAGE plproxy;

3. Функции на прокси-сервере создаются с такой же сигнатурой, что и на удаленном сервере. В теле прокси-функции нужно определять лишь путь до удаленного сервера:

CREATE FUNCTION pwd_check(text, text) RETURNS boolean 
$$
  SELECT 1 FROM users WHERE name=$1 AND PWD=$2;
  IF FOUND THEN RETURN true;
  ELSE RETURN false;
$$ LANGUAGE plpgsql;


CREATE FUNCTION pwd_check(text, text) RETURNS boolean 
$$
  CLUSTER userdb_cluster;
  PARTITION BY hashtext($1);
$$ LANGUAGE plproxy;

4. Есть возможность выполнять произвольные SQL запросы:

CREATE FUNCTION get_user_location(text) RETURNS text AS $$
    CLUSTER 'userdb';
    RUN ON hashtext($1);
    SELECT email FROM users WHERE user = $1;
$$ LANGUAGE plproxy;

Недостатки и ограничения

  • все запросы и вызовы функций вызываются в autocommit-режиме на удаленных серверах
  • в теле функции разрешен только один SELECT; при необходимости нужно писать отдельную процедуру
  • при каждом вызове прокси-сервер стартует новое соединение к бакенд-серверу; в высоконагруженных системах целесообразно использовать менеджер для кеширования соединений к бакенд-серверам, для этой цели идеально подходит PgBouncer
  • изменение конфигурации кластера (количества партиций, например) требует перезапуска прокси-сервера
 

PgBouncer

PgBouncer представляет собой простой и быстрый менеджер соединений для PostgreSQL. Он поддерживает три режима управления соединениями:

  1. Session Pooling. Наиболее "вежливый" режим. При начале сессии клиенту выделяется соединение с сервером; оно приписано ему в течение всей сессии и возвращается в пул только после отсоединения клиента.
  2. Transaction Pooling. Клиент владеет соединением с бакендом только в течение транзакции. Когда PgBouncer замечает, что транзакция завершилась, он возвращает соединение назад в пул.
  3. Statement Pooling. Наиболее агрессивный режим. Соединение с бакендом возвращается назад в пул сразу после завершения запроса. Транзакции с несколькими запросами в этом режиме не разрешены, так как они гарантировано будут отменены.

К достоинствам PgBouncer относится очень низкое потребление памяти (менее 2КБ на соединение по умолчанию), отсутствие привязки к одному серверу баз данных (может работать с разными хостами), возможность изменения большинства настроек без рестарта, а также возможность онлайн-перезапуска:  PgBouncer сам перенесет открытые сокеты в новый процесс. Из недостатков стоит отметить разве что отсутствие поддержки протоколов старее V3, что требует использования в качестве бакенда сервера PostgreSQL версии новее, чем 7.4, но в настоящее время это уже не является серьезным ограничением. Для низкоуровневой работы с сокетами PgBouncer использует libevent.

 

WalMgr

Скрипт, написанный на python, максимально облегчающий процедуру разворачивания сервера с горячим бекапом на основе трансфера логов, а в случае отказа мастер-сервера -- быстрого переключения нагрузки на резервный сервер. Все весьма просто:

[ .. настраиваем небольшие конфиг файлы .. ]



master$ walmgr setup

master$ walmgr backup

slave$ walmgr restore



[ .. мастер-сервер отказал, переключаем нагрузку на резервный сервер с бекапом: ]



slave$ walmgr restore

 

Londiste

Представляет собой движок для организации репликации, написанный на языке python. Основные принципы: надежность и простота использования; из-за этого данное решение имеет меньше функциональности, чем Slony-I. Londiste использует в качестве транспортного механизма очередь PgQ (описание этого более чем интересного проекта остается за рамками данного мини-обзора, поскольку он представляет интерес скорее для низкоуровневых программистов баз данных, чем для конечных пользователей -- администраторов СУБД PostgreSQL). Отличительными особенностями решения являются:

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

К недостаткам можно отнести:

  • отсутствие поддержки sequence делает невозможным поддержание failover-сервера актуальным (для этой цели нужно использовать WalMgr)
  • отсутствие поддержки каскадной репликации

Пример использования Londiste с инсталляцией:

$ londiste.py replic.ini provider install
$ londiste.py replic.ini subscriber install
$ londiste.py replic.ini replay -d
$ londiste.py replic.ini provider add users orders
$ londiste.py replic.ini subscriber add users
 

Ссылки

  1. "Skype делится своими проектами", Новости PostgreSQL, Postgresmen
  2. "PostgreSQL at Skype", доклад Skype на PostgreSQL Anniversary Summit 2006
  3. Public Database Projects, Skype Developer Zone
  4. PlProxy, Skype Developer Zone
  5. SkyTools, Skype Developer Zone
  6. PgBouncer, Skype Developer Zone
  7. PlProxy, PgFoundry
  8. SkyTools, PgFoundry
  9. PgBouncer, PgFoundry

 

Any feedback is welcome at iz at sai dot msu dot ru

Apr 2007