Páginas

jueves, 15 de mayo de 2014

Usando dos Document Managers con Doctrine MongoDB Bundle

Hola a todos.

Retomo mi blog después de bastante tiempo de olvido. En estos meses, mi vida a dado un vuelco en el ámbito profesional, ya que después de presentar mi proyecto de fin de carrera (con bastantes buenos resultados) entré a formar parte de The MadVideo Inc..

En esta nueva etapa, Symfony y MongoDB han pasado a formar parte de mi día a día. En este espacio os cuento como resolví el problema de utlizar dos Document Managers desde DoctrineMongoDBBundle para tener dos bases de datos separadas en diferentes servidores. Es importante indicar que las bases de datos están configuradas en dos replica sets de MongoDB.

Según la documentación oficial, si queremos indicar en nuestra configuración la presencia de dos Document Managers debemos indicarlo de esta forma:

doctrine_mongodb:
    default_database: hello_%kernel.environment%
    default_connection: conn2
    default_document_manager: dm2
    connections:
        conn1:
            server: mongodb://localhost:27017
        conn2:
            server: mongodb://localhost:27017
    document_managers:
        dm1:
            connection: conn1
            mappings:
                AcmeDemoBundle: ~
        dm2:
            connection: conn2
            mappings:
                AcmeHelloBundle: ~

Hasta aquí todo bien. El problema es que con esta configuración no habremos configurado la conexión para utilizar un replica set. Según encontramos en la documentación, la configuración de la conexión con los replica sets debería quedar de la siguiente forma:

connections:
        conn1:
            server: mongodb://mdb1:27017,mdb2:27017
            options:
                connect: true
                replicaSet: true
        conn2:
            server: mongodb://mdb3:27017,mdb4:27017
            options:
                connect: true
                replicaSet: true
            

Según se puede observar, tenemos un replica set compuesto por los servidores mdb1 y mdb2 y otro compuesto por los servidores mdb3 y mdb4.

Ahora viene lo más importante de todo: ambos replica sets deben ser identificado con distinto nombre. Esta identificación de la que hablo es la que se asigna al replica set cuando lo iniciamos desde la consola de mongo con el comando rs.initiate().

Si no tenemos en mente esto e identificamos ambos replica sets de la misma forma, Symfony tomará ambas conexiones indistintamente para cualquier Document Manager, y por tanto el sistema no producirá los resultados deseados.

Para terminar, hay que hacer un retoque en la configuración para asegurarnos que Symfony identifica cada replica set de forma unívoca:

connections:
        conn1:
            server: mongodb://mdb1:27017,mdb2:27017
            options:
                connect: true
                replicaSet: MyReplicaSet1
        conn2:
            server: mongodb://mdb3:27017,mdb4:27017
            options:
                connect: true
                replicaSet: MyReplicaSet2
            

Como se puede observar, el primer replica set se identifica con el nombre MyReplicaSet1, el segundo con MyReplicaSet2.

De esta forma no tendremos problemas a la hora de redirigir cada petición a base de datos al servidor correcto.