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

Como o pgBouncer ajuda a acelerar o Django


Além de economizar a sobrecarga de conectar e desconectar onde isso é feito em cada solicitação, um pool de conexões pode canalizar um grande número de conexões de clientes para um pequeno número de conexões de banco de dados reais. No PostgreSQL, o número ideal de conexões de banco de dados ativas geralmente está em torno de ((2 * core_count) + Effective_spindle_count) . Acima desse número, a taxa de transferência e a latência pioram.

Às vezes as pessoas dirão "Quero dar suporte a 2.000 usuários, com tempo de resposta rápido". É praticamente garantido que se você tentar fazer isso com 2.000 conexões de banco de dados reais, o desempenho será horrível. Se você tiver uma máquina com quatro processadores quad-core e o conjunto de dados ativo estiver totalmente armazenado em cache, verá um desempenho muito melhor para esses 2.000 usuários canalizando as solicitações por meio de cerca de 35 conexões de banco de dados.

Para entender por que isso é verdade, esse experimento mental deve ajudar. Considere uma máquina servidora de banco de dados hipotética com apenas um recurso para compartilhar -- um único núcleo. Esse núcleo dividirá o tempo igualmente entre todas as solicitações simultâneas sem sobrecarga. Digamos que 100 solicitações cheguem ao mesmo tempo, cada uma delas precisando de um segundo de tempo de CPU. O núcleo funciona em todos eles, dividindo o tempo entre eles até que todos terminem 100 segundos depois. Agora considere o que acontece se você colocar um pool de conexões na frente que aceitará 100 conexões de clientes, mas fizer apenas uma solicitação de cada vez ao servidor de banco de dados, colocando em uma fila todas as solicitações que chegarem enquanto a conexão estiver ocupada. Agora, quando 100 solicitações chegam ao mesmo tempo, um cliente recebe uma resposta em 1 segundo; outro recebe uma resposta em 2 segundos e o último cliente recebe uma resposta em 100 segundos. Ninguém teve que esperar mais tempo para obter uma resposta, a taxa de transferência é a mesma, mas a latência média é de 50,5 segundos em vez de 100 segundos.

Um servidor de banco de dados real tem mais recursos que podem ser usados ​​em paralelo, mas o mesmo princípio vale, uma vez saturados, você só prejudica as coisas adicionando mais solicitações de banco de dados simultâneas. Na verdade, é pior do que o exemplo, porque com mais tarefas você tem mais alternâncias de tarefas, maior contenção para bloqueios e cache, contenção de linha de cache L2 e L3 e muitos outros problemas que reduzem a taxa de transferência e a latência. Além disso, enquanto um alto work_mem configuração pode ajudar uma consulta de várias maneiras, essa configuração é o limite por nó de plano para cada conexão , portanto, com um grande número de conexões, você precisa deixar isso muito pequeno para evitar a liberação do cache ou até mesmo levar à troca, o que leva a planos mais lentos ou coisas como tabelas de hash derramando no disco.

Alguns produtos de banco de dados criam efetivamente um pool de conexões no servidor, mas a comunidade PostgreSQL assumiu a posição de que, como o melhor pool de conexões é feito mais próximo do software cliente, eles deixarão isso para os usuários gerenciarem isso. A maioria dos poolers terá alguma maneira de limitar as conexões de banco de dados a um número fixo, enquanto permite mais solicitações de clientes simultâneas do que isso, enfileirando-as conforme necessário. Isso é o que você quer, e deve ser feito em um transacional base, não por declaração ou conexão.