1. ホーム
  2. sql

[解決済み】MongoDBがv4以前にACID準拠でなかったことの本当の意味は?

2022-04-04 15:52:47

質問

私はデータベースの専門家ではなく、正式なコンピュータサイエンスのバックグラウンドもないので、ご容赦ください。 私は、どのような 実世界 を使用した場合に起こる可能性のある否定的な事柄。 v4以前のMongoDBバージョン でなかったもの。 ACID に準拠している。 これは、ACID非対応のデータベースにも適用されます。

MongoDBは、以下のようなことができるそうですね。 アトミック操作 しかし、伝統的なロックと複雑なトランザクションはサポートしていません。 また、データベーストランザクションの重要性も理解しています。例えば、データベースが銀行用で、すべてが同期している必要がある複数のレコードを更新している場合、停電があった場合にトランザクションを初期状態に戻し、信用が購入と等しくなるようにしたい、等々です。

しかし、MongoDBの話になると、データベースが実際にどのように実装されているかという技術的な詳細を知らない私たちは、次のような発言を投げかけるようになります。

MongoDBはMySQLやPostgresよりずっと高速ですが、100万分の1の確率で、"正しく保存されない"ことがあります。

この「正しく保存されない」というのは、こういう理解のことです。MongoDB に書き込んだ瞬間に停電になった場合、特定のレコード(たとえば 10 個の属性を持つドキュメントでページビューをトラッキングしている場合)には、ドキュメントの 1 つに 5 個の属性しか保存されていない可能性があります... つまり、ページビューカウンターは時間とともに "slightly" ずれていくのです。 つまり、時間の経過とともに、ページビューカウンターは少しずつずれていくことになります。 というのも、特別に mongodbアトミック操作 この操作はアトミックであることが保証されていません。

そこで質問ですが、MongoDBが"save correctly"しない場合があるのはいつ、なぜなのか、正しい解釈は何でしょうか。 ACIDのどの部分を満たさないのか、どんな状況なのか、そしてその0.001%のデータが外れたときにどうやって知ることができるのか? これはどうにかして直せないのでしょうか? もしそうでなければ、これは、あなたの users というのも、レコードが保存されないことがあるからです。 でも、1/1,000,000のユーザーは、もう一度サインアップしてみる必要があるかもしれませんね。

私はただ、MongoDBのようなACID非準拠のデータベースでネガティブなことがいつ/なぜ起こるのか、そして理想的には標準的な回避策(データをクリーンアップするバックグラウンドジョブの実行や、このためにSQLのみを使用するなど)があるかどうかをリストアップしたいと思っています。

解決方法は?

MongoDBで失うもののひとつに、マルチコレクション(テーブル)トランザクションがあります。 MongoDB のアトミック修飾子は、ひとつのドキュメントに対してしか使えません。

もし、ある商品を在庫から取り除くのと同時に、誰かの注文に追加する必要があるのなら、それはできません。 在庫と注文という2つのものが同じドキュメントに存在しない限り(おそらく存在しないでしょう)。

私が取り組んでいるアプリケーションでも、これとまったく同じ問題に遭遇し、2つの解決策から選択することになりました。

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

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

これは明らかに理想的ではありませんが、大規模なアプリケーションの中でmongodbが完璧にニーズに合わない唯一の部分です。 それに、今のところ完璧に動作しています。 これは多くのシナリオで可能ではないかもしれませんが、私が使っているドキュメント構造のため、うまくフィットしています。

2)トランザクションデータベースをMongoDBと併用する。 絶対に必要なものにはMySQLを使ってトランザクションを提供し、MongoDB(または他のNoSQL)には得意なことをさせるというのが一般的です。

もし1の解決策が長期的にうまくいかない場合は、MongoDBとMySQLの組み合わせについてさらに調査するつもりですが、今のところ1の解決策が私のニーズに合っています。