Usando pconnect em vários bancos de dados em PHP no Apache2

3

Estou executando o PHP no preforked (MOD_PHP) em um servidor apache2. A configuração está no Linux Ubuntu 10.04. O banco de dados que estou usando é um banco de dados firebird 2.5.2. O servidor apache2 está executando em um cluster da web que consiste em 8 servidores da web.

Em um momento, tivemos sérios problemas de desempenho devido a grandes picos nas solicitações para o aplicativo (passamos horas espiadas). O gargalo mostrou ser a quantidade de conexões de banco de dados necessárias para resolver o número de solicitações que vieram em um tempo muito curto. O Firebird não lidou com isso muito bem e os pedidos simplesmente expiraram.

Esse tipo de banco de dados não tem um pool de conexão e é por isso que tenho usado o pconnect no PHP para aliviar o estresse do banco de dados. Isso persiste a conexão com o banco de dados no processo apache2. Este foi um grande aumento de desempenho. O lado ruim é que tivemos que deixar um processo do apache2 receber muitos pedidos antes que ele seja rotacionado e mantemos muito processo do apache2 rodando mesmo que não haja carga para ele. Os servidores da web estão executando com 70 processos apache cada. Isso é para manter as conexões abertas e prontas. Basicamente, tentamos fazer o apache2 nosso pool de conexões. Isso funciona. Quando um usuário solicita o aplicativo, o identificador do banco de dados está pronto e o Firebird não precisa se preocupar com o custo de criar uma nova conexão com o banco de dados.

Agora aqui está a minha pergunta. Agora precisamos ter muitos bancos de dados - pequenos. Mas todos eles serão executados no cluster de servidores apache2. Isso significa que, no tempo de vida de um processo apache2, é muito provável que ele obtenha conexões persistentes com vários bancos de dados (talvez 80-100).

Estou preocupado em como o apache2 lidará com esse cenário. Existe um limite no apache2 em quantas conexões ele pode manipular? Será que vai ficar mais lento .. vai crescer na memória e lidar com tudo perfeito?

Por enquanto, não há nada a fazer sobre o sharding do banco de dados. Nós (como equipe de desenvolvimento) não gostávamos nem um pouco da ideia de dividir os bancos de dados. Mas não havia luz verde para reescrever o aplicativo e criar uma nova estrutura de banco de dados para obter mais desempenho do código. Hardware, por enquanto, é a resposta. Há também questões legais que nos obrigam a dividir em vários bancos de dados para incluir dados. Mas isso é que eu fico um pouco preocupado com o que o apache2 é capaz de lidar.

Alguém sabe?

    
por Ronnie Jespersen 08.01.2014 / 10:33

2 respostas

0

Antes de tudo, você deve considerar esse design com cuidado. As melhores práticas no design de banco de dados são evitar dividir seus dados em vários bancos de dados o máximo possível. É claro que há exceções (por exemplo, se você precisa permitir que os clientes / aplicativos modifiquem seus esquemas), mas, em geral, a escalabilidade na direção de se conectar a vários bancos de dados é ruim. Além disso, consultas cruzadas a bancos de dados são difíceis de escrever, caras e mal suportadas em muitos sistemas de bancos de dados (da maioria), forçando você a fazer um monte de trabalho que poderia ser feito pelo banco de dados no aplicativo. A manutenção é um pesadelo quando você tem um relacionamento N..N entre bancos de dados e aplicativos.

Em segundo lugar, sua explicação é um pouco incerta, mas eu me pergunto como você usa sua piscina ..? Normalmente, com o prefork você mantém alguns servidores ao redor, para melhorar a latência. Contanto que o servidor viva, a conexão persistente também deve. O pconnect realmente não se agrupa, nem parece que você faz. Você poderia dar um exemplo mais claro?

Em terceiro lugar, existem vários recursos que você pode executar. É provável que os Descritores de Arquivos apresentem um problema bem cedo, e ter muitas conexões de cada trabalhador consumirá memória no Apache e no banco de dados. Além disso, estabelecer as conexões será caro, mesmo com um pool de conexão. Se você não puder reduzir o número de bancos de dados em uso, provavelmente terá de reduzir o volume de recursos desperdiçados por conexões db obsoletas.

Se alguém me procurasse com um design que exigisse conexões com centenas de bancos de dados de um funcionário do Apache, eu os enviaria diretamente para a prancheta. Há muitas coisas que podem e vão dar errado com esse design. Mesclar os bancos de dados ou, se isso não for possível, colocar em uma camada intermediária.

edite: Ok, agora as coisas estão um pouco mais claras.

Isso é parcialmente uma questão de planejamento de capacidade, e normalmente é impossível fornecer boas respostas. Mas, para esclarecer alguns pontos.

  1. Como mencionado anteriormente, você tem muitos limites que pode atingir ao tentar estabelecer conexões com muitos bancos de dados. Os descritores de arquivos e a memória (especialmente memória compartilhada) provavelmente serão os primeiros limites atingidos.

  2. O que você está fazendo não é realmente o pool de conexões, pois as conexões persistentes nunca serão retornadas a um pool. São apenas conexões persistentes, o que economiza alguma sobrecarga.

  3. Minha abordagem, se realmente preciso fragmentar os bancos de dados dessa maneira (que eu acho que é uma escolha de design muito ruim) seria dedicar processos do Apache para cada banco de dados. Dessa forma, reduzo o risco de acumular muitas conexões persistentes em um processo. Não há como, até onde eu sei, fazer isso sem ter várias instalações do Apache2 e dividir as solicitações com base no FQDN. Soluções alternativas que eu consideraria seriam consumir o custo de usar o connect e usar o cache para tentar minimizar o número de ocorrências do banco de dados e examinar se não consigo separar o aplicativo da web da confusão do banco de dados.

por 31.03.2014 / 13:26
0

Is there a limit in apache2 in how many connections it can handle?

Sim, é limitado por seus parâmetros de configuração (MaxClients, MaxServers, KeepAlive, MaxRequestsPerChild etc) e pela CPU / memória (com o KeepAlive você pode trocar alguns de um pelo outro).

will it just grow in memory...?

Sim, quanto mais conexões, mais threads e mais memória são usadas. Observe quanta memória cada thread do Apache está usando (20 - 30MB é típico) para que você possa ter uma idéia do máximo que você pode ter, considerando a RAM disponível. Se você desativar os módulos não utilizados, consumirá menos memória por thread.

Opcionalmente, se a memória é um problema, você pode usar o Nginx em vez do Apache, já que o nginx consome uma quantidade (pequena) fixa de memória.

Em qualquer caso, normalmente, o afunilamento não estará no servidor da Web, mas no banco de dados e na E / S de disco, que são endereçados com o cache e as configurações do banco de dados / otimização de código / esquema.

Em última análise, isso se parece com uma pergunta de planejamento de capacidade e, no final, a única maneira de saber com certeza se seu sistema pode lidar com várias conexões é tentar replicar a configuração (ou uma parte representativa dela) em um teste. ambiente e benchmark.

    
por 31.03.2014 / 19:25