2010-07-16 6 views
11

À l'heure actuelle, nous avons une grande application Perl qui utilise DBI brut pour se connecter à MySQL et exécuter des instructions SQL. Il crée une connexion à chaque fois et se termine. Commençons à approcher la limite de connexion de mysql (200 à la fois)Perl Connection Pooling

Il semble que DBIx::Connection prend en charge le pool de connexions de la couche application.

Quelqu'un a-t-il eu de l'expérience avec DBIx::Connection? Y a-t-il d'autres considérations pour la mise en commun des connexions?

Je vois aussi mod_dbd qui est un mod Apache qui a l'air de gérer le regroupement de connexions. http://httpd.apache.org/docs/2.1/mod/mod_dbd.html

+1

J'utilise DBIx :: Connector (DBIx :: Class utilise en interne) et c'est merveilleux ... Je regroupe ces connexions avec un wrapper d'objets Moose qui renvoie les instances d'objets existantes si les paramètres de connexion sont identiques. Ce n'est pas difficile de rouler les vôtres. – Ether

+1

@Ether - vaut une réponse, IMHO – DVK

+0

@DVK: ok, je l'ai développé avec une réponse ... – Ether

Répondre

8

Je n'ai aucune expérience avec DBIx :: Connexion, mais j'utiliser DBIx::Connector (essentiellement ce que DBIx :: classe utilise en interne, mais inline) et il est merveilleux ...

Je POOL ces connexions avec une enveloppe d'objet Moose qui remet en arrière des instances d'objets existants si les paramètres de connexion sont identiques (ce qui fonctionnerait le même pour tout objet DB sous-jacent):

package MyApp::Factory::DatabaseConnection; 
use strict; 
use warnings; 

use Moose; 

# table of database name -> connection objects 
has connection_pool => (
    is => 'ro', isa => 'HashRef[DBIx::Connector]', 
    traits => ['Hash'], 
    handles => { 
     has_pooled_connection => 'exists', 
     get_pooled_connection => 'get', 
     save_pooled_connection => 'set', 
    }, 
    default => sub { {} }, 
); 

sub get_connection 
{ 
    my ($self, %options) = @_; 

    # some application-specific parsing of %options here... 

    my $obj; 
    if ($options{reuse}) 
    { 
     # extract the last-allocated connection for this database and pass it 
     # back, if there is one. 
     $obj = $self->get_pooled_connection($options{database}); 
    } 

    if (not $obj or not $obj->connected) 
    { 
     # look up connection info based on requested database name 
     my ($dsn, $username, $password) = $self->get_connection_info($options{database}); 
     $obj = DBIx::Connector->new($dsn, $username, $password); 

     return unless $obj; 

     # Save this connection for later reuse, possibly replacing an earlier 
     # saved connection (this latest one has the highest chance of being in 
     # the same pid as a subsequent request). 
     $self->save_pooled_connection($options{database}, $obj) unless $options{nosave}; 
    } 

    return $obj; 
} 
+0

pouvez-vous s'il vous plaît partager le code entier aussi s'il vous plaît fournir la solution pour atteindre avec Rose :: DB gestionnaire – Sethu

+0

@Sethu qui est le code entier. et je ne recommanderais pas d'utiliser Rose :: DB dans tous les cas. – Ether

+0

est la fonction prédéfinie get_connection_info? si ce n'est pas aimablement partager cette fonction aussi. – Sethu

5

tout en vous assurant: vous connaissez DBI->connect_cached(), non? C'est un remplacement direct pour connect() qui réutilise dhh, si possible, pendant la durée de vie de votre script Perl. Peut-être votre problème est résolu en ajoutant 7 caractères :)

Et, les connexions de MySQL sont relativement bon marché. En cours d'exécution avec votre base de données au max_connections=1000 ou plus ne sera pas en soi causer des problèmes. (Si vos clients demandent plus de travail que votre DB ne peut en supporter, c'est un problème plus grave, que max_connections pourrait mettre de côté mais que vous ne résolvez pas.)

+0

Je pense que la version gratuite de MySQL ne prend en charge que 200 connexions? – bonez

+1

La version gratuite de MySQL n'est nullement paralysée. (Sauf si vous comptez la GPL, haha.) Même les applications de grande taille et mal écrites ne devraient pas nécessiter plus de quelques milliers, mais vous pouvez définir [max_connections] (http://dev.mysql.com/doc/refman/5.0 /en/server-system-variables.html#sysvar_max_connections) aussi haut que vous voulez, si vous avez la mémoire et les descripteurs de fichiers. –

+2

Il n'y a pas de version "payante" de MySQL. Tout est GPL. Au mieux, Oracle pourrait avoir un contrat de support que vous pourriez payer, mais le logiciel lui-même est entièrement gratuit et non-inscrit. –