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


Je ne suis pas un expert en base de données et n'ai pas de formation en informatique, alors supportez-moi. Je veux savoir le genre de monde réel des choses négatives qui peuvent se produire si vous utilisez MongoDB, qui n'est pas ACIDE conforme. Ceci s'applique à toute base de données ACID non conforme.

Je comprends que MongoDB peut effectuer Opérations atomiques, mais qu'ils ne «soutiennent pas le verrouillage traditionnel et les transactions complexes», principalement pour des raisons de performance. Je comprends également l'importance des transactions de base de données, et l'exemple de quand votre base de données est pour une banque, et vous mettez à jour plusieurs enregistrements qui doivent tous être synchronisés, vous voulez que la transaction retourne à l'état initial s'il y a un coupure de courant, donc le crédit équivaut à l'achat, etc.

Mais lorsque je discute 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 à lancer des déclarations comme:

MongoDB est bien plus rapide que MySQL et Postgres, mais il y a une petite chance, comme 1 sur un million, qu'il "ne sauvera pas correctement".

Cette partie "ne sauvera pas correctement" fait référence à cette compréhension: S'il y a une panne de courant au moment où vous écrivez à MongoDB, il y a une chance pour un enregistrement particulier (disons que vous suivez les pages vues avec 10 attributs chacun), que l'un des documents n'a sauvegardé que 5 des attributs ... ce qui veut dire qu'avec le temps, vos compteurs de pages vues seront "légèrement" désactivés. Vous ne saurez jamais à quel point vous savez qu'ils seront 99,999% corrects, mais pas à 100%. C'est parce que, sauf si vous avez spécifiquement fait cela un opération atomique mongodb, l'opération n'est pas garantie d'avoir été atomique.

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 0.001% de vos données est désactivé? Cela ne peut-il pas être résolu d'une manière ou d'une autre? Si non, cela semble signifier que vous ne devriez pas stocker des choses comme votre users table dans MongoDB, car un enregistrement peut ne pas enregistrer. Mais encore une fois, cet utilisateur au 1/1 000 000 pourrait avoir juste besoin de "réessayer de s'inscrire", non?

Je cherche juste une liste de quand / pourquoi des choses négatives arrivent avec une base de données ACID non conforme comme MongoDB, et idéalement s'il y a une solution de contournement standard (comme exécuter un travail d'arrière-plan pour nettoyer des données, ou seulement utiliser SQL pour ceci, etc.) .


204
2017-08-22 15:35


origine


Réponses:


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

Si vous devez retirer un article de l’inventaire et l’ajouter à 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 deux solutions possibles existent:

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 la vérification du client est terminée, je retire ensuite les éléments du reservedInventory. 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.

C'est évidemment loin d'être idéal, mais c'est la seule partie d'une grande application où mongodb ne correspond pas parfaitement au besoin. De plus, cela fonctionne parfaitement jusqu'à présent. Cela peut ne pas être possible dans de nombreux cas, mais en raison de la structure du document que j'utilise, cela convient bien.

2) Utiliser une base de données 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.


118
2017-08-22 16:17



Il n'est pas correct que MongoDB ne soit pas compatible ACID. Au contraire, MongoDB est ACID-compilant au niveau du document.

Toute mise à jour d'un document unique est

  • Atomique: il complète complètement ou non
  • 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 le souci d'écriture approprié)

Ce que MongoDB n'a pas c'est 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 un commit en deux phases.


119
2017-07-06 02:29



Une bonne explication est contenue dans "Starbucks n'utilise pas de validation en deux phases".

Il ne s'agit pas de bases de données NoSQL, mais cela illustre le fait que parfois vous pouvez vous permettre de perdre une transaction ou d'avoir temporairement votre base de données dans un état incohérent.

Je ne considérerais pas que c'est quelque chose qui doit être «réparé». La solution consiste à utiliser une base de données relationnelle compatible ACID. Vous choisissez une alternative NoSQL lorsque son comportement répond aux exigences de votre application.


31
2017-08-22 15:43



Je pense que d'autres personnes ont déjà donné de bonnes réponses. Cependant, je voudrais ajouter qu'il y a des DB ACID NOSQL (comme http://ravendb.net/ ). Donc ce n'est pas seulement la décision NOSQL - pas d'ACID vs relationnel avec ACID ....


15
2018-02-28 09:10



"ne sauvera pas correctement" pourrait signifier:

  1. Par défaut, MongoDB n'enregistre pas vos modifications sur le lecteur immédiatement. Il est donc possible que vous disiez à un utilisateur que la mise à jour est réussie, qu'une coupure 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 arrive 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 Engagement en deux phasesou restructurer votre schéma pour que les mises à jour soient apportées à un seul document. Voir cette question: Bases de données de documents: données redondantes, références, etc. (MongoDB spécifiquement)


11
2017-09-01 14:05



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 base de données 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 ils sont toujours en mémoire, ils sont capables de se débrouiller 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 base de données traditionnel qui est parfois obligé d'effectuer des E / S en tenant un pagelock ou un rowlock.


5
2018-04-16 22:35



S'il vous plaît lire à propos de la Propriétés ACID pour mieux comprendre.

Aussi dans la documentation MongoDB vous pouvez trouver un question et réponse.

MongoDB n'est pas conforme à ACID. Lire ci-dessous pour une discussion de l'ACID   conformité.

  1. MongoDB est Atomic au niveau du document uniquement. 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 Consitent par défaut. Cependant, vous pouvez lire à partir de serveurs secondaires dans un jeu de réplicas. Vous pouvez seulement 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 Isolation (toujours selon la définition ci-dessus):
  1. Pour les systèmes avec plusieurs lecteurs et graveurs simultanés, MongoDB   permettre aux clients de lire les résultats d'une opération d'écriture avant la   écriture des retours d'opération.
  2. Si le mongod se termine avant que le journal ne commette, même s'il s'agit d'une écriture   retourne avec succès, les requêtes peuvent avoir des données lues qui n'existeront pas   après le redémarrage du mongod.

toutefois, MongoDB modifie chaque document isolément (pour les insertions et   mises à jour); au niveau du document uniquement, pas sur les transactions multi-documents.

  1. En ce qui concerne Durability - vous pouvez configurer ce comportement avec le write concern option, pas sûr cependant. 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.


4
2018-05-09 04:56



À partir de MongoDB v4.0, les transactions ACID multi-documents doivent être prises 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


4
2018-02-18 17:01



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 Percolateur de Google et dans le CafardDB mais rien ne vous empêche de l'utiliser avec MongoDB.

J'ai créé un visualisation pas à pas de telles transactions. J'espère que cela vous aidera à les comprendre.

Si vous êtes d'accord avec le niveau d'isolement en lecture engagée, il est logique de jeter un coup d'oeil sur Les transactions RAMP par Peter Bailis. Ils peuvent également être implémentés pour MongoDB du côté client.


1
2018-03-04 02:34