2011-08-11 13 views
14

Estoy trabajando en un proyecto que tiene algunos datos importantes. Esto significa que no podemos perder nada si la luz o el servidor se cae. Estamos usando MongoDB para la base de datos. Me gustaría asegurarme de que mis datos estén en la base de datos después de insertar y deshacer todo el lote si no se insertó un elemento. Sé que la filosofía detrás de Mongo es que no necesitamos transacciones, pero ¿cómo puedo asegurarme de que mis datos se almacenan de manera segura después de la inserción, en lugar de enviarlos a un "agujero negro"?¿Qué tan seguro es el modo seguro de MongoDB en los insertos?

  • ¿Debería hacer una búsqueda?

  • ¿Debo usar algunos comandos específicos de mongoDB?

  • debo usar sharding incluso si un servidor es suficiente para satisfacer
    la velocidad y por la forma en que no garantiza nada si la luz
    deja de funcionar?

¿Cuál es la mejor solución?

Respuesta

14

Su mejor opción es utilizar Write Concerns (Escribir preocupaciones): esto le permite decirle a MongoDB qué tan importante es una información. La Prevención de escritura más rápida también es la menos segura: los datos no se descargan en el disco hasta la próxima descarga programada. El más seguro confirmará que los datos se han escrito en el disco en varias máquinas antes de regresar.

La preocupación de escritura que está buscando es FSYNC_SAFE (al menos eso es lo que se llama desde el punto de vista de Java driver) o REPLICAS_SAFE que confirma que sus datos se han replicado.

Tenga en cuenta que MongoDB no tiene transacciones en el sentido tradicional: su retroceso tendrá que hacerse a mano ya que no puede decirle a la base de datos de Mongo que haga esto por usted.

La otra cosa que necesita hacer es utilizar la relativamente nueva --journal opción (que utiliza un registro de escritura anticipada), o utilizar conjuntos de réplicas para compartir sus datos en muchas máquinas con el fin de maximizar la integridad de datos en caso de choque/pérdida de potencia. El sharding no es tanto una protección contra fallas de hardware como un método para compartir la carga cuando se trata de grandes conjuntos de datos: la fragmentación no debe confundirse con conjuntos de réplicas, que es una forma de escribir datos en más de un disco más de una máquina.

Por lo tanto, si sus datos son lo suficientemente valiosos, definitivamente debe utilizar conjuntos de réplicas, tal vez incluso la ubicación de esclavos en otros centros de datos/zonas de disponibilidad/bastidores/etc. para proporcionar la resistencia que necesita.

Hay/seré (no puedo recordar si esto ya se ha implementado) una forma de especificar la prioridad de nodos individuales en un conjunto de réplicas, de modo que si el maestro deja de funcionar, el nuevo maestro elegido es uno en el mismo centro de datos si esa máquina está disponible (es decir, para evitar que un esclavo del otro lado del país se convierta en maestro a menos que realmente sea la única otra opción).

+0

Gracias por una muy buena y vasta respuesta. Esperaré por otras respuestas por algún tiempo y si no encuentro nada nuevo lo aceptaré, gracias –

+0

tl; dr: ¡Estás jodido de cualquier manera! – Mrchief

5

Recibí una muy buena respuesta de una persona llamada GVP en grupos de google.Lo citaré (básicamente, que se suma a la respuesta de Rich):

me gustaría estar seguro de que mis datos están en la base de datos después de la inserción y deshacer todo el lote si no se ha insertado un elemento .

Este es un tema complejo y hay varias concesiones que tiene que considerar aquí.

¿Debo usar sharding?

Sharding es para escalar escrituras. Para la seguridad de los datos, desea buscar un conjunto de réplica .

¿Debo usar algunos comandos específicos de mongoDB?

Lo primero a tener en cuenta es el modo "seguro" o "getLastError()" como indicado por Andreas. Si emite una escritura "segura", sabrá que la base de datos ha recibido la inserción y ha aplicado la escritura. Sin embargo, MongoDB solo se vacía en el disco cada 60 segundos, por lo que el servidor puede fallar sin los datos en el disco.

Lo segundo a tener en cuenta es "escribir en diario" (v1.8 +). Con el diario encendido, los datos se descargan al diario cada 100 ms. Entonces tienes un margen de tiempo más pequeño antes de la falla. Los controladores tienen una opción "fsync" (verifique ese nombre) que va un paso más allá de "safe", espera que se confirme que los datos tienen vacíos en el disco (es decir, el archivo de diario). Sin embargo, esto solo cubre un servidor. ¿Qué sucede si el disco duro en el servidor acaba muere? Bueno, necesitas una segunda copia.

Tercero a tener en cuenta es la replicación . Los controladores admiten un parámetro "W" que dice "replicar esta información en N nodos" antes de volver. Si la escritura no llega a Nodos "N" antes de un tiempo de espera determinado, la escritura falla (se produce la excepción ). Sin embargo, debe configurar "W" correctamente según el número de nodos en su conjunto de réplicas. Una vez más, debido a que un disco duro podría fallar, incluso con el diario, querrá ver la replicación. Luego hay una replicación en los centros de datos que es demasiado larga para obtener aquí. Lo último que debe considerar es su requerimiento de "rodar de vuelta". Desde mi entendimiento, MongoDB no tiene esta capacidad de "revertir" . Si está haciendo una inserción por lotes, lo mejor que obtendrá es una indicación de los elementos que fallaron.

Aquí hay un enlace al controlador PHP en este caso: http://it.php.net/manual/en/mongocollection.batchinsert.php Deberá verificar los detalles sobre la replicación y el parámetro W. Creo que las mismas limitaciones se aplican aquí.

Cuestiones relacionadas