MongoDBがv4以前にACIDに準拠していないとはどういう意味ですか?


226

私はデータベースの専門家ではなく、正式なコンピュータサイエンスの経歴もありません。ACIDに準拠していなかったv4より前の古いMongoDBバージョンを使用した場合に発生する可能性のある現実の否定的なことを知りたいのですが。これは、ACIDに準拠していないデータベースに適用されます。

MongoDBはアトミック操作を実行できますが、主にパフォーマンス上の理由により、「従来のロックと複雑なトランザクションをサポート」しないことを理解しています。また、データベーストランザクションの重要性と、データベースが銀行向けであり、すべてを同期する必要のある複数のレコードを更新する場合の例を理解しています。停電により、クレジットは購入と同等になります。

しかし、MongoDBについての会話に入ると、データベースが実際にどのように実装されているかについての技術的な詳細を知らない私たちは、次のようなステートメントを投げかけ始めます。

MongoDBはMySQLやPostgresよりもはるかに高速ですが、100万分の1のように、「正しく保存されない」可能性はわずかです。

「正しく保存されない」という部分は、この理解に言及しています。MongoDBに書き込んでいる瞬間に停電があった場合、特定のレコードが存在する可能性があります(たとえば、10の属性を持つドキュメントのページビューを追跡しているとします)それぞれ)、1つのドキュメントは5つの属性しか保存しませんでした...つまり、時間の経過とともにページビューカウンターが「少し」オフになります。どれだけ正確かは決してわかりません。99.999%正しいことはわかりますが、100%は正しくありません。これは、具体的にこれをmongodbのアトミック操作にしない限り、操作がアトミックであることが保証されないためです。

ですから、私の質問は、MongoDBが「正しく保存」されない場合とその理由の正しい解釈は何ですか?ACIDのどの部分が満足できませんか。また、どのような状況で、0.001%のデータがオフであるかをどのようにして知ることができますか?これはどういうわけか修正できませんか?そうでない場合users、レコードが保存されない可能性があるため、MongoDBにテーブルのようなものを格納してはならないことを意味しているようです。しかし、その場合も、その1 / 1,000,000ユーザーは「もう一度サインアップしてみる」必要があるかもしれません。

MongoDBのようなACID非準拠データベースでネガティブなことが発生するタイミング/理由のリストを探しているだけです。理想的には、標準の回避策(バックグラウンドジョブを実行してデータをクリーンアップするか、SQLだけを使用するなど)がある場合に理想的です。 。

回答:


133

MongoDBで失うものの1つは、マルチコレクション(テーブル)トランザクションです。MongoDBのアトミック修飾子は、単一のドキュメントに対してのみ機能します。

アイテムを在庫から削除し、同時に誰かの注文に追加する必要がある場合-できません。これらの2つ(在庫と注文)が同じドキュメントに存在しない限り(おそらく存在しません)。

私が取り組んでいるアプリケーションでこの非常に同じ問題が発生し、2つの解決策から選択できました。

1)できる限りドキュメントを構造化し、アトミック修飾子をできる限り使用します。残りのビットについては、バックグラウンドプロセスを使用して、同期していない可能性のあるレコードをクリーンアップします。たとえば、アイテムを在庫から削除し、アトミック修飾子を使用して同じドキュメントのreservedInventory配列に追加します。

これにより、商品が在庫にないことを常に知ることができます(顧客が予約しているため)。顧客がチェックアウトしたら、reservedInventoryからアイテムを削除します。これは標準的なトランザクションではなく、顧客がカートを放棄する可能性があるため、放棄されたカートを探して見つけ、予約済み在庫を使用可能な在庫プールに戻すためのバックグラウンドプロセスが必要です。

これは明らかに理想的とは言えませんが、mongodbがニーズに完全に適合しない大規模アプリケーションの唯一の部分です。さらに、これまでのところ問題なく動作します。これは多くのシナリオで可能ではないかもしれませんが、私が使用しているドキュメント構造のため、それはうまく適合します。

2)MongoDBと組み合わせてトランザクションデータベースを使用します。MySQLを使用して、MongoDB(または他のNoSQL)に最適な処理を実行させながら、トランザクションを絶対に必要とするものに提供することは一般的です。

#1の私のソリューションが長期的に機能しない場合は、MongoDBとMySQLの組み合わせについてさらに調査しますが、今のところ#1は私のニーズに適しています。


27
MongoDBのアトミック修飾子は、単一のコレクションに対してのみ機能します」=>「単一のドキュメントに対して」という意味だと思います。
アッシリア

2
優れた情報。MySQLの使用を提案することを除いて、一般的に優れた回答。
Doug Molineux 2014年

MonMongoDBで失うものの1つは、マルチコレクション(テーブル)トランザクションです。MongoDBのアトミック修飾子は、mongoドキュメント(docs.mongodb.com/v3.2/core/write-operations-atomicity)の単一のドキュメントに対してのみ機能します:「MongoDBでは、書き込み操作は単一のレベルでアトミックですドキュメントは、操作が単一のドキュメント内の複数の埋め込みドキュメントを変更した場合でも。
yoav.str 2017年

5
マルチドキュメントACIDトランザクションの欠如は、もはや当てはまりません。MongoDBは、v4.0で提供されることを発表しました。mongodb.com/blog/post/multi-document-transactions-in-mongodbを
Grigori Melnik

1
今のところ、MongoDB 4.0以降は、マルチドキュメントトランザクションを使用するACID準拠のmongodb.com/transactionsです。見ていmongodb.com/blog/post/...
Ratah

134

MongoDBがACIDに準拠していないことは実際には正しくありません。反対に、MongoDBはドキュメントレベルで ACIDに準拠しています

単一のドキュメントへの更新は

  • Atomic:完全に完了するか、完了しません
  • 一貫性:「部分的に適用された」アップデートはどの読者にも表示されません
  • 分離:繰り返しになりますが、「汚い」読み取りは見られません。
  • 耐久性:(適切な書き込みを考慮して)

MongoDBにないのはトランザクションです。つまり、ロールバックでき、ACIDに準拠する複数のドキュメントの更新です。

2フェーズコミットを使用すると、単一のドキュメントに対するACID準拠の更新に基づいてトランザクションを構築できることに注意してください。


3
2フェーズコミットのトランザクションはACIDに準拠していないことに注意してください。何らかの理由で、リンクをたどるまで反対のことを推測しました。
ジャスティンC

1
書き込み関連の構成に関係なく、ドキュメントレベルでの分散MongoDBの耐久性についていくつかの質問があります。オープンソースツールのJepsenは、MAJORITY書き込みの懸念があっても、ネットワークパーティションに直面するとデータが失われる可能性があることを発見しました。こちらの記事をご覧ください:aphyr.com/posts/284-call-me-maybe-mongodb
jrullmann

9
ADBを単一のドキュメントのレベルで使用することは、RDBMSの単一のレコードと同等の意味で、多くの場合役に立ちません。トランザクションの用語は単一のテーブルには関係せず、2フェーズコミットのメカニズムを持ち、いくつかのXAResourceを使用することもできます。したがって、単一のドキュメントをACID準拠として参照することはやや問題があります。
Yair Zaslavsky、2016

5
イエールに同意する。「ドキュメントレベルでのACID準拠」はセールスポイントではありません。基本的には「ACIDに準拠していない」という意味です。ACIDは、「1つの行/ドキュメント/エンティティ」についてだけのものではありませんでした。データベース全体でデータの一貫性を保つことです。
joshua.paling 2016年

34

「Starbucksは2フェーズコミットを使用しない」に適切な説明があります

これはNoSQLデータベースに関するものではありませんが、トランザクションを失ったり、データベースを一時的に不整合な状態にしたりすることが許される場合があることを示しています。

私はそれを「修正」する必要があるものだとは思わないでしょう。修正は、ACID準拠のリレーショナルデータベースを使用することです。その動作がアプリケーションの要件を満たしている場合は、NoSQLの代替を選択します。


1
他の類推と同様に、制限があります。ソフトウェアでは、新しいArray [Cashiers]を作成してそれぞれに同期トランザクションを処理させるのは簡単ですが、その実際のコストは途方もなく高くなります。
HRJ

16

他の人はすでに良い答えを出したと思います。ただし、ACID NOSQL DB(http://ravendb.net/など)があることを付け加えておきます。したがって、それは意思決定NOSQLだけではありません-ACIDとACIDとの関係はありません...


1
@subGateに感謝します。ravenDBの経験を共有でき、実際に要件を満たしている人はいますか?
Nir Pengas 2013年

12

「正しく保存されない」とは、

  1. デフォルトでは、MongoDBは変更をドライブにすぐに保存しません。そのため、ユーザーに「更新が成功しました」と伝える可能性があり、停電が発生して更新が失われます。MongoDBは、更新の「持続性」のレベルを制御するオプションを提供します。他のレプリカが(メモリ内で)この更新を受信するまで待機したり、ローカルジャーナルファイルへの書き込みが発生するまで待機したりできます。

  2. 複数のコレクションや、同じコレクション内の複数のドキュメントに対しても、簡単な「アトミック」な更新はありません。Two Phase Commitやスキーマを再構築して単一のドキュメントを更新することで回避できるため、ほとんどの場合問題にはなりません。次の質問を参照してください:ドキュメントデータベース:冗長データ、参照など(特にMongoDB)


10

MongoDB v4.0以降、マルチドキュメントACIDトランザクションがサポートされます。スナップショット分離により、トランザクションはグローバルに一貫したデータのビューを提供し、データの整合性を維持するためにオールオアナッシングの実行を強制します。

彼らは関係の世界からのトランザクションのように感じます、例えば:

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

https://www.mongodb.com/blog/post/multi-document-transactions-in-mongodbを参照してください


MongoDB4.0の最初のリリース候補が出ている- linkedin.com/pulse/mongodb-40-rc0-now-available-grigori-melnik
グリゴリーメルニーク

5

理解を深めるために、ACIDプロパティについてお読みください。

また、MongoDBのドキュメントでは、質問と回答を見つけることができます。

MongoDBはACIDに準拠していません。ACIDコンプライアンスの説明については、以下をお読みください。

  1. MongoDBはAドキュメントレベルでのみトミックです。これは、リレーショナルデータベースシステムからわかるアトミックの定義、特に上記のリンクに準拠していません。この意味で、MongoDBはACIDのAに準拠していません。
  2. MongoDBはCデフォルトでオンサイトです。 ただし、レプリカセットのセカンダリサーバーから読み取ることができます。この場合、結果整合性のみ可能です。これは、少し古いデータを読むことを気にしない場合に役立ちます。
  3. MongoDBはIソレーションを保証しません(これも上記の定義に従います)。
  1. 複数のリーダーとライターが同時に存在するシステムの場合、MongoDBを使用すると、クライアントは書き込み操作が戻る前に書き込み操作の結果を読み取ることができます。
  2. ジャーナルがコミットする前にmongodが終了した場合、書き込みが正常に返されても、mongodの再起動後に存在しないデータをクエリが読み取った可能性があります。

ただし、MongoDBは各ドキュメントを個別に変更します(挿入と更新用)。複数ドキュメントのトランザクションではなく、ドキュメントレベルのみ。

  1. D耐久性に関して-この動作はwrite concernオプションで設定できますが、確かではありません。多分誰かがよりよく知っています。

NoSQLをACID制約などに移行するために、いくつかの研究が進行中であると思います。NoSQLデータベースは通常高速であり、ACID制約によりパフォーマンスが大幅に低下する可能性があるため、これは課題です。


4

アトミックが単一のコレクションに対する作業を変更する唯一の理由は、mongodb開発者が最近、データベースロックをコレクション全体の書き込みロックと交換したためです。ここでの同時実行の増加はトレードオフの価値があると判断しました。中核となるのは、mongodbがメモリマップファイルであり、バッファプールの管理をマシンのvmサブシステムに委任していることです。これは常にメモリ内にあるため、非常に粗いロックを回避できます。保持している間はメモリ内のみの操作を実行するため、非常に高速になります。これは、ページロックまたは行ロックを保持しているときにI / Oを実行しなければならない場合がある従来のデータベースシステムとは大きく異なります。


これにより同時実行性が向上する理由を説明していただけますか?ここに明らかなものがない場合は申し訳ありません。
batbrat

@batbrat:同じデータベース内の異なるコレクションに同時に書き込もうとする2つのクライアントについて考えてみます。データベースがロックされている場合、クライアントの1つは、書き込みが発生する前に、もう1つが完了するのを待たなければなりません。コレクションロックを使用すると、両方のクライアントが同時に書き込むことができます。これが、同時実行性の向上の意味です。もちろん、両方のクライアントが同じコレクションに書き込もうとすると、一方は待機する必要があります。
jrullmann、2014

2

「MongoDBでは、単一のドキュメントに対する操作はアトミックです」- それは過去のものです

MongoDB 4.0の新しいバージョンでは、次のことができます。

ただし、複数のドキュメントの更新の原子性または複数のドキュメントの読み取り間の一貫性が必要な状況では、MongoDBはレプリカセットに対してマルチドキュメントトランザクションを実行する機能を提供します。マルチドキュメントトランザクションは、複数の操作、コレクション、データベース、ドキュメントで使用できます。マルチドキュメントトランザクションは、「オールオアナッシング」の命題を提供します。トランザクションがコミットすると、トランザクションで行われたすべてのデータ変更が保存されます。トランザクションのいずれかの操作が失敗した場合、トランザクションは中止され、トランザクションで行われたすべてのデータ変更は、表示されることなく破棄されます。トランザクションがコミットするまで、トランザクション内の書き込み操作はトランザクションの外部からは見えません。

以下のためのいくつかの制限がありますがどのようにしてどのような操作を行うことができます。

Mongo Docを確認してください。 https://docs.mongodb.com/master/core/transactions/


1

ストレージがキーごとの線形化をサポートし、比較および設定をサポートしている場合(MongoDBに該当)、クライアント側でアトミックマルチキー更新(シリアライズ可能なトランザクション)を実装できます。このアプローチは、GoogleのパーコレーターCockroachDBで使用されていますが、MongoDBでの使用を妨げるものはありません。

このようなトランザクションの段階的な視覚化を作成しました。あなたがそれらを理解するのに役立つことを願っています。

読み取りコミット分離レベルで問題がなければ、Peter BailisによるRAMPトランザクションを確認することは理にかなっています。これらは、クライアント側のMongoDBにも実装できます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.