PHP -> pool de conexão persistente Mysql SEM mysql_pconnect - Possível?

12

Eu tenho tentado descobrir uma boa maneira de fazer isso por um tempo agora. Mas tive dificuldade em encontrar as peças certas para fazer isso. Eu estou supondo que isso deve ser possível.

Para colocá-lo em termos simples, aqui é o que eu gostaria de realizar:

PHP / Other front end -> [SOCKET] ->

Locally hosted 'pooler' -> [Pool of persistent TCP/IP connection(s)]->

Externally hosted MySQLD

Existe tal ferramenta / maneira de fazer as coisas?

Nós basicamente gostaríamos de implementar conexões mysql persistentes SEM usar mysql_pconnect.

Peço respeitosamente que não comecemos a discutir sobre como as conexões persistentes não são necessárias, etc. Estamos ficando sem portas TIME_WAIT e estamos tendo outros problemas que seriam resolvidos se esse tipo de sistema fosse implementado.

Então, para resumir ... Nós implementaríamos um pooler de conexões mysql que é baseado em socket local e persistiriam as conexões que são feitas com um servidor mysql hospedado externamente (LAN).

Nós não usamos transações ou qualquer outra coisa que seria afetada pelas conexões mysql sendo recicladas.

Estamos executando o Linux no front-end com um cluster master + master percona 5.5.

Obrigado!

anônimo-um
fonte

Respostas:

12

Depois de muita pesquisa, finalmente encontrei uma solução.

Como não sou muito escritor, farei o possível para tornar isso o mais conciso possível.

Até onde pude encontrar, existem 2 soluções possíveis:

Retransmissão SQL

http://sqlrelay.sourceforge.net/

Isso faz exatamente o que a pergunta pediu e muito mais. Não vou entrar em muitos detalhes sobre o que pude descobrir sobre isso, mas mencionarei que não era uma solução viável, pois não é transparente. Significando que o fluxo é o seguinte:

PHP -> Queries -> SQL Relay Extension -> SQL Relay -> Externally hosted MySQL

Portanto, isso envolveria reescrever todo o nosso código do mysql para o sql relay. Não é uma opção no nosso caso.

Tudo o que foi dito, se alguém está planejando um novo projeto de larga escala que requer qualquer um dos inúmeros recursos que o SQL Relay possui, parece bonito.

Mysql Proxy

http://forge.mysql.com/wiki/MySQL_Proxy

Esta é a solução que acabamos usando.

A chave para fazer isso fazer o que queremos é o script LUA em pool para o proxy mysql.

Esta extensão LUA pode ser encontrada em:

https://github.com/cwarden/mysql-proxy/blob/315ab806bb95b8223f5afd3d238eff2a40af03d8/lib/ro-pool.lua

Sem entrar em muitos detalhes, aqui estão algumas estatísticas básicas ... Lembre-se, isso é testado em um período de uso BAIXO:

[root@HOSTNAME etc]# netstat -na | grep ":3306 " | grep TIME_WAIT | wc
   6433   38598  572537

Depois de mudar para o mysql-proxy, e deixar as coisas resolverem:

[root@HOSTNAME etc]# netstat -na | grep ":3306 " | grep TIME_WAIT | wc
     32     192    2848

Como você pode ver claramente, as portas TIME_WAIT para o mysql caíram para quase nenhuma.

As conexões agora são de fato persistentes SEM usar mysql_pconnect / mysqli_connect (... p: hostname ...).

Vale ressaltar que parece haver algumas configurações configuráveis ​​próximas à parte superior do script lua do pooler.

min_idle_connections local

e

max_idle_connections local

Estes parecem ser bastante auto-explicativos. Exceto que: Parece que cada combinação de nome de usuário (e senha? Não testada ... provavelmente não.) Cria seu próprio conjunto de conexões persistentes.

Então multiplique max_idle_connections pelo número de usuários mysql únicos que estarão se conectando ao banco de dados. E isso deve lhe dar uma idéia de quantas conexões inativas você acabará tendo.

Então, deixe-me reiterar para que este pequeno anúncio contenha algumas palavras-chave para quem pesquisa no google:

Ao usar PHP, é possível ter conexões mysql persistentes SEM mysql_pconnect?

Sim, isso pode ser feito via SQL Relay se você não se importar em reconstruir a maior parte do seu código para direcionar suas consultas através de sua extensão OU de forma transparente usando o mysql-proxy com o script ro-pooling.lua.

Há um ano que desejamos algo assim.

APRECIAR!

anônimo-um
fonte
Por que não usar simplesmente a funcionalidade de limpeza (conforme declarada na resposta abaixo) fornecida pela função persistente do mysqli ? Se você não tem acesso ao mysqli, por que não simplesmente usar mysql_pconnecte iniciar cada conexão com algumas "funções de limpeza"?
Pacerier
4
  1. O suporte à conexão persistente foi introduzido no PHP 5.3 para a mysqliextensão. O suporte já estava presente no PDO MYSQL e no ext / mysql. A idéia por trás das conexões persistentes é que uma conexão entre um processo do cliente e um banco de dados pode ser reutilizada por um processo do cliente, em vez de ser criada e destruída várias vezes. Isso reduz a sobrecarga de criação de novas conexões sempre que necessário, pois as conexões não utilizadas são armazenadas em cache e prontas para serem reutilizadas.

  2. Diferente da extensão mysql, mysqlinão fornece uma função separada para abrir conexões persistentes. Para abrir uma conexão persistente, você deve acrescentar p: ao nome do host ao se conectar.

  3. O problema com conexões persistentes é que elas podem ser deixadas em estados imprevisíveis pelos clientes. Por exemplo, um bloqueio de tabela pode ser ativado antes que um cliente seja encerrado inesperadamente. Um novo processo do cliente que reutilize essa conexão persistente obterá a conexão "como está". Qualquer limpeza precisaria ser feita pelo novo processo do cliente antes que ele pudesse fazer bom uso da conexão persistente, aumentando a carga sobre o programador.

A conexão persistente da extensão mysqli, no entanto, fornece código de manipulação de limpeza interno. A limpeza realizada pelo mysqli inclui:

Rollback active transactions

Close and drop temporary tables

Unlock tables

Reset session variables

Close prepared statements (always happens with PHP)

Close handler

Release locks acquired with `GET_LOCK()`

Isso garante que as conexões persistentes estejam em um estado limpo ao retornar do conjunto de conexões, antes que o processo do cliente as use.

A extensão mysqli faz essa limpeza chamando automaticamente a função C-API mysql_change_user().

O recurso de limpeza automática possui vantagens e desvantagens. A vantagem é que o programador não precisa mais se preocupar em adicionar código de limpeza, como é chamado automaticamente. No entanto, a desvantagem é que o código pode ser um pouco mais lento, pois o código para executar a limpeza precisa ser executado sempre que uma conexão é retornada do pool de conexões.

É possível desativar o código de limpeza automática, compilando o PHP com o MYSQLI_NO_CHANGE_USER_ON_PCONNECTdefinido.

Nota:

A extensão mysqli suporta conexões persistentes ao usar o MySQL Native Driver ou a MySQL Client Library.

Além disso, você pode consultar estes links: http://www.mysqlperformanceblog.com/2006/11/12/are-php-persistent-connections-evil/

Mahesh Patil
fonte