Balanceando a carga
e particionando os
dados com
PL/PROXY
Palestrante: João Cosme de Oliveira Júnior
Título da Apresentação Objetivos: ● Objetivo do particionamento. Funcionamento do pl/proxy. Conceitos do pl/proxy. Instalaçao do pl/proxy. Configuração do pl/proxy.
Cenário simples de utilização do pl/proxy
O usuário disse com brilho nos
olhos...
● Quero um sistema que replique on-line...
● Que tenha balanceamento de carga.... (loading
balance)
● Que tenha alta-disponibilidade (HA) ● E que …
A pergunta : Será que ele realmente necessita disso tudo?
– Não existe uma caixa mágica!! – Existem “tijolos”...
O que é um particionamento em
banco de dados?
●
É um design no projeto físico do banco de dados.
●Separar o que é logicamente uma tabela em
tabelas fisicas menores.
– Horizontal – Verical
Benefícios do particionamento
●
Performance de consultas podem ser melhoradas
drasticamente.
●
Quando consultas ou updates acessam uma
grande porção da partição, performance pode ser
alcançada utilizando-se de um acesso sequencial
na particao, ao invés de um uso indexado de uma
tabela gigantesca.
●
Dados pouco utilizados podem ser migrados para
Entendi mas não estou visualizando ...
●
Seguinte cenário:
– Tabela com milhões de usuários
– Milhões de usuário conectados a um único banco de
Como consequência..
●
Diminuiríamos a carga em cima de um único
servidor
●
Promoveríamos o particionamento dos dados
Como é realizado o particionamento?
●
Baseado em uma “chave de particionamento” é
aplicado um critério que determina a partição.
●
Hash('login') : determina a partição em que o
login do usuário encontrará.
●
Select @(hashtext('joao') %2)
●Select @(hashtext('cosme') %2)
●Select @(hashtext('junior') % 2)
O que é um proxy?
●
O Proxy é o “CARA” que faz o serviço sujo para
O que é plproxy?
●
O plproxy é uma linguagem criada dentro de um
banco de dados Postgresql (assim como outras
linguagens como plpgsql…. )
●
Possibilita acesso remoto em outros databases
assim como o dblink.
●
Segundo Kaiv, o plproxy é um dblink
Instalado plproxy
Baixar os fontes http://pgfoundry.org/projects/plproxy/
apt-get install build-essentials postgresql-server-dev-8.x PATH:=$PATH:/usr/local/pgsql/bin
Baixado o fonte, tar -xzvf plproxy….
make && make install. apt-get install flex bison
Um exemplo vale mais do que mil
palavras... ou não...
● Como eu faria para conectar remotamente em outro
banco de dados a partir de um outro
– Resposta!!!!! DBLINK (eu sempre olho a
documentação do dblink...)
● Exemplo: Gostaria a partir do meu banco de dados atual
conectar em outro bd e executar uma consulta
● Create or replace function consulta_mail_funcionario (nome text) returns text as $$
CONNECT 'dbname=outrobd';
select mail from tb_funcionario where username = nome; $$ language plproxy
Sintaxe PL/PROXY
●
Similar a plpgsql.
●
Contém somente 4 sentenças.
– CONNECT, CLUSTER, RUN e SELECT
●
Cada função deve ter o par :
– CONNECT ou CLUSTER + RUN
●
Select opcional, função de mesma assinatura
●Run opcional, run on any (random)
Sintaxe PL/PROXY
●
CONNECT
– CONNECT 'libpq connstr';
●
CLUSTER
– CLUSTER 'cluster_name';
– Especifica em que cluster irá executar. O nome do
cluster é especificado na função plproxy.get_cluster_partition()
●
RUN ON
Sintaxe PL/PROXY
●
SELECT
– PLPROXY gera a query baseada na assinatura da
função mas pode ser sobrescrito pela sentenca SELECT.
Criando o ambiente
● Criaremos 3 bancos de dados localmente. ● create database bdproxy;
● create database bd1; ● create database bd2;
● Criaremos uma tabela “usuarios” que conterá o login e o
mail de cada usuário do nosso sistema. Essa tabela deve ser criada no bd1, bd2
Criando o ambiente
● Suporte a plpgsql nos bancos de dados ● Create language plpgsql;
● Suporte a plproxy no bdproxy
● psql -U postgres -h localhost bdproxy <
/usr/local/pgsql/share/contrib/plproxy.sql
● Criação do esquema plproxy no bdproxy ● create schema plproxy;
Criando o primeiro Cluster
●
Existem 3 funções que devem ser criadas no
banco de dados que servirá como proxy, no caso
o bdproxy:
● plproxy.get_cluster_version()
● plproxy.get_cluster_partitions() ● plproxy.get_cluster_config()
Criando o primeiro Cluster
● plproxy.get_cluster_version(cluster_name)
● Essa função é chamada em cada requisição, e
deve retornar o número da versão da
configuração corrente para um cluster em particular. Se a versão retornada por essa
função for maior do que a versão cacheada pelo plproxy , então a configuração e as informações sobre as partições irão sofrer um reload na
Criando o primeiro Cluster
● plproxy.get_cluster_partitions(cluster_name)
● Essa função é chamada quando uma nova
configuração de partição sofre um reload. Essa função deve retornar as strings de conexão para as partições no cluster. As strings de conexão devem ser retornadas na ordem correta. O
número total de strings de conexão que devem ser retornadas devem ser potência de 2.
Criando o primeiro Cluster
● plproxy.get_cluster_config()
● Deve retornar parametros de configuração como
keys - valores em pares. Todas os parâmetros são opcionais.
Lembrem-se!!!
●
Sempre 3 funções para configuração do proxy!!
– plproxy.get_cluster_version – plproxy.get_cluster_partitions – plproxy.get_cluster_config
Criando o primeiro Cluster
CREATE OR REPLACE FUNCTION
plproxy.get_cluster_version(cluster_name text) RETURNS int4 AS $$
BEGIN
IF cluster_name = 'usercluster' THEN RETURN 1;
END IF;
RAISE EXCEPTION 'Cluster Desconhecido'; END;
Criando o primeiro Cluster
CREATE OR REPLACE FUNCTION
plproxy.get_cluster_partitions(cluster_name text) RETURNS SETOF text AS $$
BEGIN
IF cluster_name = 'usercluster' THEN
RETURN NEXT 'dbname=bd1 host=127.0.0.1'; RETURN NEXT 'dbname=bd2 host=127.0.0.1'; RETURN;
END IF;
RAISE EXCEPTION 'Cluster Desconhecido'; END;
Criando o primeiro Cluster
CREATE OR REPLACE FUNCTION plproxy.get_cluster_config (cluster_name text, out key text, out val text)
RETURNS SETOF record AS $$ BEGIN
RETURN; END;
Criando o primeiro Cluster
Conferindo as funções criadas no bdproxy– select proname from pg_proc where proname ~
'cluster'; proname get_cluster_version get_cluster_config get_cluster_partitions (3 rows)
Inserindo dados
●
A inserção é realizada através do.... proxy
●
Invocaremos uma função de inserção no bdproxy
e ele vai fazer o balanceamento nos databases
particionados.
Inserindo Dados – passo 1 Proxy
CREATE OR REPLACE FUNCTION insert_user(username text, mail text)
RETURNS integer AS $$ CLUSTER 'usercluster';
RUN ON hashtext(username); $$ LANGUAGE plproxy;
CLUSTER - é o nome do cluster que nós setamos lá no
plproxy.get_cluster_version
RUN ON hashtext (username) - Agora sim…… O particionamento
acontece aqui, lembra da função hash lá em cima???? ou seja baseado no username ocorre obtemos um balanceamento nos servidores :),
Inserindo Dados –Passo 2 bds
CREATE OR REPLACE FUNCTION insert_user(username text, mail text)
RETURNS integer AS $$
insert into login values(username,mail); Select 1;
Inserindo Dados – Passo 3
● Elaborei esse shell script para automatizar a inserção,
você pode inserir diretamente no bdproxy usando seu cliente de sua preferência.
for i in $(seq 1 500) do
psql -U postgres -h localhost -c ” select
insert_user(’usuario$i’,'[email protected]’);” bdproxy done
Recuperando os dados
● Inserimos os dados e podemos observar que eles estão
particionados.
● E agora como recuperaríamos esses dados?
● Bem, da mesma forma que o bdproxy particiona os
dados utilizando a função hash , baseando-se no mesmo hash ele sabe em quais partições estão os dados.
Recuperando os dados
● Inserimos os dados e podemos observar que eles estão
particionados.
● E agora como recuperaríamos esses dados?
● Bem, da mesma forma que o bdproxy particiona os
dados utilizando a função hash , baseando-se no mesmo hash ele sabe em quais partições estão os dados.
Recuperando os dados
create or replace function get_user_mail (usuario text) returns text as $$
CLUSTER 'usercluster';
RUN ON hastext(username);
select mail from login where username= usuario; $$ language plproxy;