Программное обеспечение, Личные разработки, Проекты, Портфолио, Хитрости, Заметки, Статьи...

PostgreSQL: Конфигурация PL/Proxy Кластера

PL/Proxy ClusterДанная писанина объясняет как конфигурировать кластер PostgreSQL с использованием PL/Proxy. Приступим сразу к мат. части.

PL/Proxy может быть использован в режиме CONNECT или CLUSTER.

В режиме CONNECT PL/Proxy выступает в роли прозрачного проксирующего элемента к другой базе данных. Каждая функция PL/Proxy содержит строку соединения к другой базе данных для библиотеки libpq. При выполнении функции на текущем сервере, все операции будут физически происходить на удаленном сервере.

PL/Proxy также может быть использован в режиме CLUSTER. В режиме кластера PL/Proxy предоставляет поддержку порционирования данных на множестве серверов баз данных.

Когда используется режим CONNECT не требуется никаких специальных конфигураций. Однако, при использовании режима CLUSTER требуется настройка кластеров с помощью API кластеров или SQL/MED.

API конфигурирование кластера

Следующие функции используются для конфигурирования кластера с использованием PL/Proxy:


plproxy.get_cluster_version(cluster_name text)

returns integer


Функция plproxy.get_cluster_version вызывается при каждом запросе. Данная функция должна возвращать версию каждого кластера текущей конфигурации. Если функция возвращает число типа Целое и оно больше, чем число, которое было в кэше plproxy, то конфигурация и информация о кластере будет получены заново из функций get_cluster_config() и get_cluster_partitions(). 

Вот простой пример реализации функции get_cluster_version():

CREATE OR REPLACE FUNCTION plproxy.get_cluster_version(cluster_name text)
RETURNS int4 AS $$
BEGIN
      IF cluster_name = 'a_cluster' THEN
          RETURN 1;
      END IF;
      RAISE EXCEPTION 'Unknown cluster';
END;
$$ LANGUAGE plpgsql;


plproxy.get_cluster_partitions(cluster_name text)
returns setof text


Функция вызывается, когда необходимо получить конфигурацию партиций кластера. Она должна возвращать строку соединения с партициями кластера. Строки соединения должны быть возвращены в правильном порядке. Количество возвращаемых строк соединения должно быть кратно двум. Если две или более строк идентичны (указывают на соединение с одним и тем же кластером) то будет использовано одно соединение. Данная функция полезна, если у вас количество партиций не кратно двум. Ну в самом деле, не покупать же еще один сервер если он не нужен.

Если в возвращаемой строке соединения не фигурирует параметр "user=", то будет использован текущий пользователь (user=CURRENT_USER) для соединения с партицией. Использование "рутового" пользователя postgres запрещено.

Несколько советов о том, как передавать пароли для соединения:

  • Храните пароли в файлах .pgpass / pg_service.conf. Данный прием вполне безопасен. Единственное неудобство в том, что Вы не сможете изменить пароли непосредственно из базы данных. Вам нужно будет редактировать эти файлы.
  • Загружайте пароли из таблиц/файлов и передавайте их в строке соединения. Есть прокол в безопасности. Пользователи СУБД смогут увидеть эти пароли.
  • Используйте один пароль для всех пользователей и передавайте его в строке соединения. Данный способ опасен в двойне. Пользователи СУБД могут увидеть пароль со всеми вытекающими.
  • Используйте авторизацию с помощью пулера (Pooling), который слушает соединения только на локальной машине или еще лучше на UNIX SOCKET. Это отличная комбинация. Так как при установке PgBouncer вы получаете в свой кластер Connection Pooling + PgBouncer умеет считывать пароли непосредственно из файлов безопасности PostgreSQL (pg_auth) и использовать их для открытия соединения с вашими партициями.
  • Использовать доверенное соединение с партициями. Откровенно плохая идея.

Пример функции get_cluster_partitions при хранении каждой из таблиц в разных партициях:

CREATE OR REPLACE FUNCTION plproxy.get_cluster_partitions(cluster_name text)
RETURNS SETOF text AS $$
BEGIN
      IF cluster_name = 'a_cluster' THEN
          RETURN NEXT 'dbname=part00 host=127.0.0.1';
          RETURN NEXT 'dbname=part01 host=127.0.0.1';
          RETURN NEXT 'dbname=part02 host=127.0.0.1';
          RETURN NEXT 'dbname=part03 host=127.0.0.1';
          RETURN;
      END IF;
      RAISE EXCEPTION 'Unknown cluster';
END;
$$ LANGUAGE plpgsql;


plproxy.get_cluster_config(in cluster_name text,
out key text, out val text)
returns setof record

Функция get_cluster_config() возвращает массив типа ключ=значение. Все ключи опциональны и не обязательны. Временные параметры задаются в секундах. Если значение 0 или NULL, то это означает что параметр отключен и будет использовано значение по умолчанию.

  • connection_lifetime - Максимальное время жизни соединения к удаленной базе данных, которое будет постоянно открыто. Если значение не установлено, то соединение будет длиться столько, сколько будет оставаться.
  • query_timeout - Если запрос не дает результат, указанное в этой опции время, то соединение закрывается. Если этот параметр установлен, то на удаленном сервере должен быть установлен параметр statement_timeout и обязательно установлен в меньшее значение чем query_timeout.
  • disable_binary - Не использовать бинарный ввод/вывод для этого кластера.
  • connect_timeout - Если соединение не открылось за отведенное время, то оно не открывается.

Пример функции:

CREATE OR REPLACE FUNCTION plproxy.get_cluster_config(
in cluster_name text,
out key text,
out val text)
RETURNS SETOF record AS $$
BEGIN
      -- будем использовать один и тотже конфиг для всех кластеров
      key := 'connection_lifetime';
      val := 30*60; -- 30m
      RETURN NEXT;
      RETURN;
END;
$$ LANGUAGE plpgsql;


Определение кластеров с помощью SQL/MED

В PostgreSQL 8.4 и выше можно настроить кластеризацию PL/Proxy при помощи SQL/MED. Весь перчик в том, что SQL/MED - это упрощенный механизм настройки кластеров который гараздо производительнее предыдущего метода (определением функций).Оба метода определения кластров могут сосуществовать в одной базе данных вместе в один и тотже момент времени. Но тогда будет действовать следующее правило: Если информация о кластере не существует в SQL/MED, то она будет запрошена с помощью функций.

Конфигурирование SQL/MED кластеров.

Во первых нам нужно создать внешний враппер данных (ВВД). В целом ВВД - это драйвер, обеспечивающий доступ к удаленным базам данных, их маршалинг и прочее. В нашем конкретном случае роль ВВД сводится к валидации параметров доступа к кластерам.

ВНИМАНИЕ: Функция валидации была испорчена во всех версиях ниже PostgreSQL 8.4.2. По этому обновитесь до более высокой версии перед ее использованием.

CREATE FOREIGN DATA WRAPPER plproxy [ VALIDATOR plproxy_fdw_validator ];

Далее нам нужно определить кластер. Данный этап можно считать завершенным после создания PostgreSQL сервера, который использует plproxy ВВД. Опции SERVER и список партиций фактически являются настройками конфигурации PL/Proxy. И будут использованы PL/Proxy для работы. 

ВНИМАНИЕ: Использование SERVER должно быть разрешено тем пользователям, которые будут работать с кластером. Иначе ничего не получится.


CREATE SERVER a_cluster FOREIGN DATA WRAPPER plproxy
OPTIONS (
      connection_lifetime '1800',
      disable_binary '1',
      p0 'dbname=part00 hostname=127.0.0.1',
      p1 'dbname=part01 hostname=127.0.0.1',
      p2 'dbname=part02 hostname=127.0.0.1',
      p3 'dbname=part03 hostname=127.0.0.1'
);

Финальным шагом будет создание маппинга пользователей на пользователей PL/Proxy. Для каждого пользователя базы данных нужно создать отдельный маппинг. Делается это так:

CREATE USER MAPPING FOR bob SERVER a_cluster
OPTIONS (user 'bob', password 'secret');

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

CREATE USER MAPPING FOR public SERVER a_cluster
OPTIONS (user 'plproxy', password 'foo');

Также можно создавать индивидуальные и публичные маппинги вместе.

Мануал актуален на 2010-01-11 11:52:40.

По большому счету является переводом официальной документации PL/Proxy. Написан как пособие для рускоязычных пользователей чтобы лучше понимать процесс конфигурации кластера с использованием PL/Proxy. Буду благодарен за любые дополнения и исправления.

Комментировать

OpenID принимается здесь Узнать больше об OpenID
  • Rambler's Top100

Об этой записи

Сообщение опубликовано 02.09.2010 09:56. Автор — Безумный Джек.

Предыдущая запись — SunSpider 0.9.1: Тестирование производительности браузеров

Следующая запись — Обновление FreeBSD при помощи Portsnap

Смотрите новые записи на главной странице или загляните в архив, где есть ссылки на все сообщения.