tutorial - sql vs nosql
¿Qué significó realmente MongoDB de no ser compatible con ACID antes de v4? (10)
No soy un experto en bases de datos y no tengo conocimientos formales de informática, así que ten paciencia. Quiero saber el tipo de cosas negativas del mundo real que pueden suceder si usa una versión antigua de MongoDB anterior a v4 , que no era compatible con ACID . Esto se aplica a cualquier base de datos no compatible con ACID.
Entiendo que MongoDB puede realizar operaciones atómicas , pero que no "admiten el bloqueo tradicional y las transacciones complejas", principalmente por razones de rendimiento. También entiendo la importancia de las transacciones de la base de datos, y el ejemplo de cuándo su base de datos es para un banco, y está actualizando varios registros que todos deben estar sincronizados, desea que la transacción vuelva al estado inicial si hay una corte de energía por lo que el crédito es igual a la compra, etc.
Pero cuando entro en conversaciones sobre MongoDB, aquellos de nosotros que no conocemos los detalles técnicos de cómo se implementan las bases de datos, comenzamos a lanzar declaraciones como:
MongoDB es mucho más rápido que MySQL y Postgres, pero hay una pequeña posibilidad, como 1 en un millón, de que "no se guarde correctamente".
La parte "no se guardará correctamente" se refiere a este entendimiento: si hay un corte de energía en el momento en que escribe a MongoDB, existe la posibilidad de un registro en particular (digamos que está rastreando visitas de página en documentos con 10 atributos cada uno), que uno de los documentos solo guardó 5 de los atributos ... lo que significa que con el tiempo sus contadores de visitas de página estarán "ligeramente" apagados. Nunca sabrás por cuánto, sabes que tendrán una corrección del 99,999%, pero no del 100%. Esto se debe a que, a menos que haya hecho específicamente una operación atómica mongodb , no se garantiza que la operación haya sido atómica.
Entonces, mi pregunta es, ¿cuál es la interpretación correcta de cuándo y por qué MongoDB no puede "guardar correctamente"? ¿Qué partes de ACID no satisfacen, y bajo qué circunstancias, y cómo sabe cuándo está apagado ese 0,001% de sus datos? ¿No se puede arreglar esto de alguna manera? Si no, esto parece significar que no debes almacenar cosas como la tabla de tus users
en MongoDB, porque un registro podría no guardarse. Pero, de nuevo, ese usuario de 1 / 1,000,000 podría necesitar simplemente "intentar registrarse otra vez", ¿no?
Solo estoy buscando una lista de cuándo / por qué suceden cosas negativas con una base de datos que no cumple con ACID como MongoDB, e idealmente si hay una solución estándar (como ejecutar un trabajo en segundo plano para limpiar datos, o solo usar SQL para esto, etc.) .
"En MongoDB, una operación en un solo documento es atómica". Eso es lo que pasa en el pasado.
En la nueva versión de MongoDB 4.0 PUEDES:
Sin embargo, para situaciones que requieren atomicidad para las actualizaciones de varios documentos o la coherencia entre las lecturas de varios documentos, MongoDB proporciona la capacidad de realizar transacciones de varios documentos contra conjuntos de réplicas. Las transacciones de documentos múltiples se pueden utilizar en múltiples operaciones, colecciones, bases de datos y documentos. Las transacciones de documentos múltiples proporcionan una propuesta de "todo o nada". Cuando se confirma una transacción, todos los cambios de datos realizados en la transacción se guardan. Si falla alguna operación en la transacción, la transacción se cancela y todos los cambios de datos realizados en la transacción se descartan sin que se vuelvan visibles. Hasta que se confirme una transacción, no se pueden ver operaciones de escritura en la transacción fuera de la transacción.
Aunque hay pocas limitaciones para cómo y qué operaciones se pueden realizar.
Revisa el Doc Mongo. https://docs.mongodb.com/master/core/transactions/
"no se guardará correctamente" podría significar:
Por defecto, MongoDB no guarda sus cambios en la unidad de inmediato. Por lo tanto, existe la posibilidad de que le diga a un usuario que "la actualización se realizó correctamente", se produce un corte de energía y la actualización se pierde. MongoDB proporciona opciones para controlar el nivel de actualización "durabilidad". Puede esperar a que las otras réplicas reciban esta actualización (en la memoria), esperar a que la escritura se realice en el archivo del diario local, etc.
No hay actualizaciones "atómicas" fáciles para varias colecciones e incluso varios documentos en la misma colección. No es un problema en la mayoría de los casos porque se puede eludir con el compromiso de dos fases o la reestructuración de su esquema para que las actualizaciones se realicen en un solo documento. Vea esta pregunta: Bases de datos de documentos: datos redundantes, referencias, etc. (MongoDB específicamente)
A partir de MongoDB v4.0, se admitirán transacciones ACID de documentos múltiples. A través del aislamiento de instantáneas, las transacciones proporcionarán una visión global de los datos y forzarán la ejecución de todo o nada para mantener la integridad de los datos.
Se sienten como transacciones del mundo relacional, por ejemplo:
with client.start_session() as s:
s.start_transaction()
try:
collection.insert_one(doc1, session=s)
collection.insert_one(doc2, session=s)
s.commit_transaction()
except Exception:
s.abort_transaction()
Ver mongodb.com/blog/post/multi-document-transactions-in-mongodb
Creo que otras personas ya dieron buenas respuestas. Sin embargo, me gustaría agregar que hay ACID NOSQL DBs (como http://ravendb.net/ ). Así que no es solo la decisión NOSQL - no ACID vs Relacional con ACID ...
En realidad no es correcto que MongoDB no sea compatible con ACID. Por el contrario, MongoDB es ACID-compilant a nivel de documento .
Cualquier actualización a un solo documento es
- Atómico: o bien completa o no lo hace.
- Consistente: ningún lector verá una actualización "parcialmente aplicada"
- Aislado: de nuevo, ningún lector verá una lectura "sucia"
- Durable: (con la correspondiente preocupación de escritura)
Lo que MongoDB no tiene es transacciones , es decir, actualizaciones de documentos múltiples que pueden revertirse y son compatibles con ACID.
Tenga en cuenta que puede generar transacciones sobre las actualizaciones compatibles con ACID en un solo documento, mediante la confirmación de dos fases .
La única razón por la que Atomic modifica el trabajo contra una sola colección es que los desarrolladores de mongodb intercambiaron recientemente un bloqueo de base de datos con un bloqueo de escritura de toda la colección. Decidir que la mayor concurrencia aquí valió la pena la compensación. En su núcleo, mongodb es un archivo mapeado en memoria: han delegado la administración del grupo de búferes al subsistema vm de la máquina. Debido a que siempre está en la memoria, son capaces de salirse con bloqueos muy complejos: realizarás operaciones solo en memoria mientras lo mantienes, lo que será extremadamente rápido. Esto difiere significativamente de un sistema de base de datos tradicional, que a veces se ve obligado a realizar E / S mientras mantiene un bloqueo de páginas o un bloqueo de fila.
Lea acerca de las ACID para obtener una mejor comprensión.
También en la documentación de MongoDB puede encontrar una pregunta y respuesta .
MongoDB no es compatible con ACID. Lea a continuación para una discusión sobre el cumplimiento de ACID.
- MongoDB es
A
tomic a nivel de documento solamente. No cumple con la definición de atómico que conocemos de los sistemas de bases de datos relacionales, en particular el enlace anterior. En este sentido, MongoDB no cumple con la A de ACID. - MongoDB es
C
onsitent por defecto. Sin embargo, puede leer desde servidores secundarios en un conjunto de réplicas. Solo puedes tener una eventual consistencia en este caso. Esto es útil si no te importa leer datos un poco desactualizados. - MongoDB no garantiza el aislamiento (de nuevo según la definición anterior):
- Para sistemas con múltiples lectores y escritores concurrentes, MongoDB permitirá a los clientes leer los resultados de una operación de escritura antes de que la operación de escritura regrese.
- Si el mongod termina antes de que se confirme el diario, incluso si la escritura se devuelve correctamente, las consultas pueden tener datos de lectura que no existirán después de que se reinicie el mongod.
Sin embargo , MongoDB modifica cada documento de forma aislada (para inserciones y actualizaciones); Sólo a nivel de documento, no en transacciones de documentos múltiples.
- En lo que respecta a
D
urabilidad, puede configurar este comportamiento con la opción dewrite concern
, aunque no estoy seguro. Tal vez alguien sabe mejor.
Creo que se está llevando a cabo una investigación para mover NoSQL hacia restricciones ACID o similares. Esto es un desafío porque las bases de datos NoSQL son generalmente más rápidas y las restricciones de ACID pueden ralentizar el rendimiento significativamente.
Puede implementar actualizaciones atómicas de múltiples claves (transacción serializable) en el lado del cliente si su almacenamiento admite la linealización por clave y compara y establece (lo que es cierto para MongoDB). Este enfoque se utiliza en Google Percolator y en CockroachDB pero nada le impide usarlo con MongoDB.
He creado una visualización paso a paso de tales transacciones. Espero que les ayude a entenderlos.
Si estás de acuerdo con el nivel de aislamiento de lectura confirmada, entonces tiene sentido echar un vistazo a las transacciones RAMP de Peter Bailis. También se pueden implementar para MongoDB en el lado del cliente.
Una buena explicación está contenida en "Starbucks no utiliza confirmación en dos fases" .
No se trata de bases de datos NoSQL, pero ilustra el punto de que a veces puede permitirse perder una transacción o tener su base de datos en un estado inconsistente temporalmente.
No lo consideraría como algo que necesita ser "arreglado". La solución es utilizar una base de datos relacional compatible con ACID. Usted elige una alternativa NoSQL cuando su comportamiento cumple con los requisitos de su aplicación.
Una cosa que se pierde con MongoDB son las transacciones de múltiples colecciones (tablas). Los modificadores atómicos en MongoDB solo pueden funcionar contra un solo documento.
Si necesita eliminar un artículo del inventario y agregarlo a la orden de alguien al mismo tiempo, no puede. A menos que esas dos cosas, inventario y pedidos, existan en el mismo documento (lo que probablemente no lo hacen).
Encontré este mismo problema en una aplicación en la que estoy trabajando y existen dos soluciones posibles:
1) Estructure sus documentos lo mejor que pueda y use modificadores atómicos lo mejor que pueda y, para el resto, use un proceso en segundo plano para limpiar los registros que pueden estar desincronizados. Por ejemplo, elimino artículos del inventario y los agrego a la matriz reservedInventory del mismo documento utilizando modificadores atómicos.
Esto me permite saber siempre que los artículos NO están disponibles en el inventario (porque están reservados por un cliente). Cuando el cliente realiza el check out, luego elimino los elementos de reservedInventory. No es una transacción estándar y, como el cliente podría abandonar el carrito, necesito algún proceso en segundo plano para buscar y encontrar los carritos abandonados y volver a colocar el inventario reservado en el grupo de inventario disponible.
Obviamente, esto no es lo ideal, pero es la única parte de una aplicación grande donde mongodb no se ajusta perfectamente a la necesidad. Además, funciona perfectamente hasta ahora. Es posible que esto no sea posible para muchos escenarios, pero debido a la estructura del documento que estoy usando, encaja bien.
2) Utilice una base de datos transaccional junto con MongoDB. Es común usar MySQL para proporcionar transacciones para las cosas que las necesitan absolutamente, mientras que MongoDB (o cualquier otro NoSQL) hace lo que mejor hace.
Si mi solución de # 1 no funciona a largo plazo, investigaré más a fondo sobre la combinación de MongoDB con MySQL, pero por ahora el # 1 se adapta bien a mis necesidades.