Qu’est-ce que MongoDB n’est pas conforme à ACID?

Je ne suis pas un expert en bases de données et je n’ai pas de formation en informatique, alors supportez-moi. Je veux connaître le genre de choses négatives du monde réel qui peuvent se produire si vous utilisez MongoDB, qui n’est pas conforme à ACID . Cela s’applique à toute firebase database non conforme ACID.

Je comprends que MongoDB peut effectuer des opérations atomiques , mais qu’elles ne “prennent pas en charge les transactions de locking et les transactions complexes”, principalement pour des raisons de performances. Je comprends également l’importance des transactions de firebase database et, par exemple, lorsque votre firebase database est destinée à une banque et que vous mettez à jour plusieurs enregistrements qui doivent tous être synchronisés, vous devez rétablir l’état initial coupure de courant donc crédit équivaut à achat, etc.

Mais lorsque je parle de MongoDB, ceux d’entre nous qui ne connaissent pas les détails techniques de la mise en œuvre des bases de données commencent à utiliser des instructions telles que:

MongoDB est beaucoup plus rapide que MySQL et Postgres, mais il y a une petite chance, comme 1 sur un million, de “ne pas enregistrer correctement”.

Cette partie «ne va pas enregistrer correctement» fait référence à cette compréhension: S’il y a une coupure de courant dès l’instant où vous écrivez à MongoDB, il y a une chance pour un enregistrement particulier (par exemple, vous suivez les pages vues dans chacun), que l’un des documents n’a enregistré que 5 des atsortingbuts… ce qui signifie qu’avec le temps, vos compteurs de pages seront “légèrement” désactivés. Vous ne saurez jamais de combien, vous savez qu’ils seront 99,999% corrects, mais pas à 100%. Ceci est dû au fait que, à moins d’en faire une opération atomique mongodb , l’opération n’est pas garantie.

Donc, ma question est la suivante: quelle est l’interprétation correcte de quand et pourquoi MongoDB ne peut pas «enregistrer correctement»? Quelles parties de l’ACID ne satisfont-elles pas et dans quelles circonstances, et comment savez-vous quand ces 0,001% de vos données sont désactivées? Cela ne peut-il pas être résolu d’une manière ou d’une autre? Si ce n’est pas le cas, cela semble signifier que vous ne devriez pas stocker de choses comme votre table d’ users dans MongoDB, car un enregistrement pourrait ne pas être enregistré. Mais encore une fois, cet utilisateur de 1 / 1.000.000 devrait juste “essayer de s’inscrire à nouveau”, non?

Je cherche simplement une liste de quand / pourquoi des choses négatives se produisent avec une firebase database non conforme à ACID comme MongoDB, et idéalement s’il y a une solution standard (exécuter un job d’arrière-plan pour nettoyer des données ou utiliser uniquement SQL pour cela, etc.) .

Une chose que vous perdez avec MongoDB est les transactions multi-collection (table). Les modificateurs atomiques dans MongoDB ne peuvent fonctionner que sur un seul document.

Si vous devez supprimer un article de votre inventaire et l’append à la commande de quelqu’un en même temps, vous ne pouvez pas le faire. À moins que ces deux choses – l’inventaire et les commandes – n’existent dans le même document (ce qui n’est probablement pas le cas).

J’ai rencontré ce problème dans une application sur laquelle je travaille et il existe deux solutions possibles:

1) Structurez au mieux vos documents et utilisez les modificateurs atomiques du mieux que vous pouvez et, pour le bit restant, utilisez un processus en arrière-plan pour nettoyer les enregistrements qui peuvent ne pas être synchronisés. Par exemple, je supprime des éléments de l’inventaire et les ajoute à un tableau reservedInventory du même document à l’aide de modificateurs atomiques.

Cela me permet de toujours savoir que les articles ne sont PAS disponibles dans l’inventaire (car ils sont réservés par un client). Lorsque le client coche, je retire ensuite les articles de l’inventaire réservé. Ce n’est pas une transaction standard et comme le client peut abandonner le panier, j’ai besoin d’un processus en arrière-plan pour passer en revue et trouver les chariots abandonnés et déplacer l’inventaire réservé dans le pool d’inventaire disponible.

Ceci est évidemment moins qu’idéal, mais c’est la seule partie d’une application volumineuse où mongodb ne répond pas parfaitement au besoin. De plus, cela fonctionne parfaitement jusqu’à présent. Cela peut ne pas être possible pour de nombreux scénarios, mais en raison de la structure du document que j’utilise, elle convient parfaitement.

2) Utilisez une firebase database transactionnelle en conjonction avec MongoDB. Il est courant d’utiliser MySQL pour fournir des transactions pour les choses qui en ont absolument besoin, tout en laissant MongoDB (ou tout autre NoSQL) faire ce qu’il fait de mieux.

Si ma solution n ° 1 ne fonctionne pas à long terme, j’étudierai plus avant la possibilité de combiner MongoDB avec MySQL, mais pour l’instant, le n ° 1 répond bien à mes besoins.

Il n’est pas correct que MongoDB ne soit pas conforme à l’ACID. Au contraire, MongoDB est un compilateur ACID au niveau du document .

Toute mise à jour d’un document unique est

  • Atomic: soit complète soit complète
  • Cohérent: aucun lecteur ne verra une mise à jour “partiellement appliquée”
  • Isolé: encore une fois, aucun lecteur ne verra une lecture “sale”
  • Durable: (avec la préoccupation d’écriture appropriée)

Ce que MongoDB n’a pas, ce sont des transactions , c’est-à-dire des mises à jour de plusieurs documents pouvant être annulées et conformes à ACID.

Notez que vous pouvez créer des transactions en plus des mises à jour compatibles ACID sur un seul document, en utilisant la validation en deux phases .

Une bonne explication est contenue dans “Starbucks n’utilise pas la validation en deux phases” .

Il ne s’agit pas de bases de données NoSQL, mais il illustre bien le fait que vous pouvez parfois vous permettre de perdre une transaction ou que votre firebase database soit temporairement dans un état incohérent.

Je ne considérerais pas cela comme quelque chose qui doit être “corrigé”. Le correctif consiste à utiliser une firebase database relationnelle compatible ACID. Vous choisissez une alternative NoSQL lorsque son comportement répond aux exigences de votre application.

Je pense que d’autres personnes ont déjà donné de bonnes réponses. Cependant, j’aimerais append qu’il existe des bases de données ACID NOSQL (comme http://ravendb.net/ ). Donc, ce n’est pas seulement la décision NOSQL – pas ACID vs relationnel avec ACID ….

“ne pas enregistrer correctement” pourrait signifier:

  1. Par défaut, MongoDB n’enregistre pas vos modifications sur le lecteur immédiatement. Il y a donc une possibilité que vous disiez à un utilisateur que “la mise à jour réussit”, qu’une panne de courant se produit et que la mise à jour est perdue. MongoDB fournit des options pour contrôler le niveau de mise à jour “durabilité”. Il peut attendre que les autres répliques reçoivent cette mise à jour (en mémoire), attendre que l’écriture se produise dans le fichier journal local, etc.

  2. Il n’y a pas de mises à jour “atomiques” faciles pour plusieurs collections et même pour plusieurs documents de la même collection. Ce n’est pas un problème dans la plupart des cas, car il peut être contourné par la validation en deux phases ou la restructuration de votre schéma pour que les mises à jour soient apscopes à un seul document. Voir cette question: Bases de données de documents: données redondantes, références, etc. (MongoDB spécifiquement)

La seule raison pour laquelle atomic modifie le travail par rapport à une seule collection est que les développeurs de mongodb ont récemment échangé un verrou de firebase database avec un verrou d’écriture large. Décider que la concurrence accrue ici valait le compromis. À la base, mongodb est un fichier mappé en mémoire: ils ont délégué la gestion du pool de mémoire tampon au sous-système vm de la machine. Comme il est toujours en mémoire, il est possible de s’en sortir avec des verrous granulaires bien sûr: vous effectuerez des opérations en mémoire uniquement en le maintenant, ce qui sera extrêmement rapide. Cela diffère de manière significative d’un système de firebase database traditionnel qui est parfois obligé d’effectuer des E / S en tenant un pagelock ou un rowlock.

À partir de MongoDB v4.0, les transactions ACID multi-documents doivent être sockets en charge. Grâce à l’isolement des instantanés, les transactions fourniront une vue cohérente des données à l’échelle mondiale et appliqueront une exécution tout ou rien pour préserver l’intégrité des données.

Ils se sentent comme des transactions du monde relationnel, par exemple:

 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() 

Voir https://www.mongodb.com/blog/post/multi-document-transactions-in-mongodb

Veuillez lire les propriétés ACID pour mieux comprendre.

Vous pouvez également trouver une question et une réponse dans la documentation MongoDB.

MongoDB n’est pas conforme à ACID. Lisez ci-dessous pour une discussion de la conformité ACID.

  1. MongoDB est uniquement A tomic au niveau du document. Il n’est pas conforme à la définition de l’atome que nous connaissons des systèmes de bases de données relationnelles, en particulier du lien ci-dessus. En ce sens, MongoDB ne respecte pas le A de ACID.
  2. MongoDB est conforme par défaut. Cependant, vous pouvez lire des serveurs secondaires dans un jeu de réplicas. Vous ne pouvez avoir une cohérence éventuelle dans ce cas. Ceci est utile si vous ne voulez pas lire des données légèrement obsolètes.
  3. MongoDB ne garantit pas la solation (encore une fois selon la définition ci-dessus):
  1. Pour les systèmes avec plusieurs lecteurs et graveurs simultanés, MongoDB permettra aux clients de lire les résultats d’une opération d’écriture avant le retour de l’opération d’écriture.
  2. Si le mongod se termine avant que le journal ne soit validé, même si une écriture réussit, les requêtes peuvent avoir des données lues qui n’existeront pas après le redémarrage du mongod.

Cependant , MongoDB modifie chaque document de manière isolée (pour les insertions et les mises à jour); au niveau du document uniquement, pas sur les transactions multi-documents.

  1. En ce qui concerne la capacité de saisie – vous pouvez configurer ce comportement avec l’option de write concern , mais vous n’êtes pas sûr. Peut-être que quelqu’un sait mieux.

Je crois que certaines recherches sont en cours pour déplacer NoSQL vers des contraintes ACID ou similaires. C’est un défi car les bases de données NoSQL sont généralement rapides et les contraintes ACID peuvent considérablement ralentir les performances.

Vous pouvez implémenter des mises à jour multi-clés atomiques (transaction sérialisable) du côté client si votre stockage prend en charge la linéarisation par clé et les comparer (c’est le cas pour MongoDB). Cette approche est utilisée dans Google Percolator et dans le CockroachDB, mais rien ne vous empêche de l’utiliser avec MongoDB.

J’ai créé une visualisation pas à pas de ces transactions. J’espère que cela vous aidera à les comprendre.

Si vous êtes d’accord avec le niveau d’isolement en lecture, alors il est logique de regarder les transactions RAMP de Peter Bailis. Ils peuvent également être implémentés pour MongoDB du côté client.

“Dans MongoDB, une opération sur un seul document est atomique” –

Dans la nouvelle version de MongoDB 4.0, vous pouvez:

Toutefois, pour les situations nécessitant une atomicité pour les mises à jour de plusieurs documents ou la cohérence entre les lectures sur plusieurs documents, MongoDB permet d’effectuer des transactions multi-documents sur des jeux de réplicas. Les transactions multi-documents peuvent être utilisées dans plusieurs opérations, collections, bases de données et documents. Les transactions multi-documents fournissent une proposition «tout ou rien». Lorsqu’une transaction est validée, toutes les modifications de données effectuées dans la transaction sont enregistrées. Si une opération dans la transaction échoue, la transaction est abandonnée et toutes les modifications de données effectuées dans la transaction sont ignorées sans jamais devenir visibles. Tant qu’une transaction n’est pas validée, aucune opération d’écriture dans la transaction n’est visible en dehors de la transaction.

Bien qu’il y ait peu de limitations pour le fonctionnement et les opérations possibles.

Vérifiez le Doc Mongo. https://docs.mongodb.com/master/core/transactions/