PostgreSQL
 sql >> Base de Dados >  >> RDS >> PostgreSQL

Algumas ideias sobre pool de recursos de baixo nível no PostgreSQL


Semana passada no CHAR(10) conferência tivemos um workshop sobre “Cloud Databases”. Simplificando:o que fazer quando os requisitos do caso de uso excedem os recursos disponíveis no servidor de banco de dados.
Este foi o tópico principal de toda a conferência, e várias soluções foram ilustradas durante o dia. Um tema comum é que nenhuma solução atende a todos os casos de uso e que cada solução vem com seu custo; portanto, você deve escolher a solução que seu caso de uso pode oferecer.


Outro ponto comum (embora implícito) tem sido o foco em soluções de “alto nível”, ou seja:conectar vários servidores de banco de dados em um nível superior para emular um único servidor com recursos maiores.
Uma vantagem óbvia é que você não precisa alterar o código bem examinado do PostgreSQL; uma desvantagem é que usando vários servidores de banco de dados com suas linhas de tempo independentes, você está perdendo algumas propriedades úteis. Dois exemplos:a perda parcial da semântica transacional gera conflitos; pré-analisar cada consulta fora do banco de dados apresenta limitações nas consultas aceitas.
A discussão foi bastante interessante, e quando Dimitri Fontaine mencionou tablespaces remotos, comecei a pensar em uma ideia relacionada, mas distinta, a saber:se uma abordagem de nível inferior ao problema do agrupamento de recursos seria realmente impraticável. Antes que eu pudesse elaborar os detalhes, o workshop terminou, e eu só pude esboçar a ideia para algumas das pessoas que estavam ao redor do quadro branco (entre elas Gabriele Bartolini, Nic Ferrier, Marko Kreen, Hannu Krosing, Greg Smith) junto com o básico perguntas “parece viável?” e “isso se parece com algo que você já conhece?”.
Um breve esboço:uma pilha de aplicativos pode ser representada dessa maneira
(application) --> (connection) --> (db server) --> (resources)

onde os recursos utilizados pelo banco de dados incluem armazenamento, RAM e CPUs. O objetivo é permitir que o aplicativo comande mais recursos para aumentar a capacidade e a velocidade. Aplicativos “inteligentes” que gerenciam vários bancos de dados podem ser representados como
(application) --> (connection) --> (db server) --> (resources)
|
+---------> (connection) --> (db server) --> (resources)

enquanto as soluções de “pooling de conexão” podem ser representadas como
(application) --> (connection) --> (db server) --> (resources)
|
+---------> (db server) --> (resources)

por soluções de “nível inferior” quero dizer algo como
(application) --> (connection) --> (db server) --> (resources)
|
+---------> (resources)

que pode parecer algo familiar, mas não é o que estou propondo aqui. Para explicar a diferença posso aumentar o detalhe e escrever
(resources) = (virtual resources) --> (physical resources)

para representar o fato de que no nível mais baixo você pode ter um mapeamento não trivial entre objetos físicos e virtuais. Por exemplo, o armazenamento SAN ou a distribuição RAID podem fornecer discos virtuais maiores juntando discos físicos menores. Esses casos podem ser retratados como
(application) --> (connection) --> (db server) --> (virt.res.) --> (ph.res.)
|
+--------> (ph.res.)

Minha proposta é reunir recursos no servidor de banco de dados nível, para que possamos ter uma “virtualização” mais eficiente utilizando o conhecimento dos casos de uso específicos para cada recurso (CPU, RAM, disco), e ao mesmo tempo evitar muitas das dificuldades do paradigma transacional. A imagem seria:
(application) --> (connection) --> (db server) --> (virt.res.) --> (ph.res.)
|
+--------> (virt.res.) --> (ph.res.)

A vantagem é que não precisamos gerenciar todos os casos de uso possíveis para cada recurso virtual; temos apenas que gerenciar (e otimizar) os casos de uso que são realmente necessários para o PostgreSQL. Por exemplo:WAL ainda deve ser escrito em armazenamento local “não virtualizado”, o bgwriter acessará recursos locais e remotos (RAM e disco), etc.
Algumas palavras finais sobre confiabilidade. Para operar adequadamente, todo o sistema precisa de cada subsistema; falhas parciais não são gerenciadas, pois essa arquitetura não é redundante. É um sistema distribuído, mas não compartilhado. Se essa arquitetura pudesse fornecer escalabilidade barata e simples por meio de um servidor de banco de dados virtual que é funcionalmente equivalente a um servidor físico com recursos maiores, a alta disponibilidade poderia ser obtida da maneira padrão, configurando dois servidores virtuais idênticos em uma configuração de Hot Standby.
A qualidade da rede tem um grande impacto no desempenho geral; esse design pode ser útil apenas se você tiver uma matriz de máquinas na mesma LAN, não apenas por motivos de velocidade, mas também porque uma falha de rede seria, na verdade, uma falha de sistema. Mesmo com essas restrições, minha opinião é que ter essa opção seria bastante útil.
Este ainda é um esboço, para ser usado como referência para futuras discussões. Próximos passos possíveis:
  • para fazer uma lista detalhada dos casos de uso de recursos
  • decidir quais tecnologias podem ajudar melhor em cada caso de uso
  • para estimar os custos reais de desempenho/desenvolvimento