Rails / Mongo a través de múltiples geo-regiones diferentes

Tengo un sistema que por necesidad requiere presencia física en tres o más lugares diferentes y necesito asesoramiento sobre la estructuración de tal manera que mi database se replica de manera oportuna sin latencia horrible. He visto el acceso mysql y la replicación ser increíblemente lento cuando el server de aplicaciones estaba tratando de hablar con un nodo que no estaba físicamente colocados. En este caso estoy usando mongodb.

  • La stack es linux / passenger / ruby ​​/ rails / mongodb.
  • La database es escribir pesado y leer la luz.
  • La infraestructura es Amazon EC2
  • La capa de aplicación debe estar físicamente ubicada en 3 o más ubicaciones diferentes. No puedo justificar este requisito más allá de lo que es un requisito. Sin embargo, la database no necesita ubicarse en más de una location si se puede escribir rápidamente desde otras ubicaciones.

De la documentation del mongo de la lectura, la réplica del mongo parece más de un candidato que sharding b / c mi almacén de datos no es enorme. Sin embargo, no veo nada que se ocupe de la cuestión de la velocidad de los serveres de comunicación a través de grandes distancias con latencia potencialmente alta.

Sus experiencias de latencia son algo preocupantes. En mis propias testings en mi networking local y rápida he notado algunas diferencias entre Mongo y MySQL cuando se trata de latencia:

  • MySQL request de ida y vuelta es a menudo less de 5ms para los artículos pequeños. A veces tan bajo como 2.
  • La petición de MongoDB RTT es aproximadamente 3 veces más lenta, alnetworkingedor de 15ms.

Parte del time MongoDB se debió al time de configuration de la connection TCP, donde el MySQL estaba utilizando una connection preexistente (agrupada). En ambos casos la database no se replicó o se fragmentó, por lo que estos pueden ser considerados como el mejor caso (para mi networking).

Mongo réplica sets pueden ayudarle aquí, pero sólo si su aplicación es capaz de tolerar la convergencia floja 1 . Para hacer la velocidad máxima, tendrás que configurar tus escrituras mongo para que sólo regresen cuando el server mongodb informe que ha recibido la escritura, y configurar tus serveres de aplicaciones para que sólo utilicen la instancia de AZ-local Mongo. Las lecturas necesitarán usar SlaveOK para que puedan leer de esa réplica AZ-local, esto mostrará escrituras locales así como replicado-escribe de los otros nodos que han convergido hasta ahora. Esto significa que cada AZ tendrá una visión ligeramente diferente de toda la database; los últimos X minutos sólo tendrán cambios locales, pero la historia profunda será converged.

Esta configuration proporcionará una latencia baja (igual a AZ) entre el server de aplicaciones y el server de bases de datos. Sin embargo, la vista de datos de los serveres de aplicaciones será diferente dependiendo del AZ que sean afectados por los usuarios de la aplicación. Si esta architecture es o no tolerable para su aplicación sólo puede ser decidida por usted.

Sin embargo, hay un problema muy grande con esto: MongoDB no es compatible con la replicación multi-master 2 , todas las escrituras deben ir al único maestro.

En la actualidad (v2.2) no es posible configurar MongoDB para permitir escrituras a los esclavos, por lo que todas las escrituras en su "escribir pesado" aplicación tendrá que ir a la única maestro de la réplica-set. Usted no menciona si la latencia de lectura es un problema, pero si lo es, entonces las lecturas de SlaveOK agarrarán al miembro de réplica Mongo local; pero a diferencia de lo anterior no puede haber recibido todas las actualizaciones del maestro, sin embargo, definitivamente habrá un retraso entre escribir-enviar y cuando se muestra el esclavo local.

Hay varios types de escritura diferentes para Mongo. El valor pnetworkingeterminado devuelve OK tan pronto como el server Mongo ha recibido completamente la escritura. El siguiente paso es el modo en el que sólo devuelve OK cuando ha realizado la escritura en el Diario. Y lo más paranoico (y por lo tanto más lento de lejos en un mongo con réplicas) es sólo devuelve OK cuando un número especificado de réplicas informan que la escritura está en sus diarios . El modo pnetworkingeterminado es más rápido, pero el último modo garantiza que las réplicas locales tengan escritura (coinheritance estricta).

Si ese maestro no está en el mismo AZ que los serveres de aplicaciones, la latencia puede muy bien ser impracticable para usted incluso con el estilo de escritura pnetworkingeterminado. Si este es el caso, mongo no funcionará para usted, ya que su aplicación existe ahora mismo . usted va a tener que pensar muy duro sobre cómo cambiar su aplicación para ser less sensible a la latencia en escritos, o utilizar una database no Mongo que puede hacer multi-master con convergencia floja.

El Mongo más cercano llega a una configuration multi-maestro es a través de sharding. Si los serveres de aplicaciones son conscientes de su location geográfica, puede include los datos geocharts en la key de fragments de Mongo. Luego, cuando se conecta a los MongoS para escribir, todas las escrituras van al set de réplicas del fragment local. Las lecturas pueden sondear toda la database (y resultarán lenta en el dibujo de los fragments no locales), por lo que esto mantendrá la coinheritance. Sin embargo, esto depende enteramente de la location que es su key de fragments.


1: Convergencia suelta , el time para que una database distribuida o replicada llegue a un estado uniforme es el time de convergencia. La convergencia suelta es un intervalo largo. La convergencia cerrada es un intervalo corto.
2: Multi-master , una database donde más de una réplica puede aceptar escrituras. Ejemplos de bases de datos que pueden hacer esto son Active Directory, OpenLDAP y algunas configuraciones de MySQL.