この記事はMongoDBのAndrew Morganが書いたものです。
たまに、僕は走る。
私はできるだけ単純なアーキテクチャを維持するのが好きです - 結局のところ、それぞれのレイヤーは独自の複雑さと管理コストをもたらします - だから私はキャッシュレイヤーが存在する理由を尋ねます。
私はまだ、キャッシュレイヤーを削除することをお勧めせずにデザインレビューを完了していません。
だから、この記事のタイトルにある質問に答えるには、いつMongoDBでキャッシュを使うべきですか? 答えは、おそらく決してありません。この記事は、なぜか説明しようとしていますが、あなたが最後まで来て、あなたのアプリケーションにそれを必要としていると思っているなら、私はあなたのアプリケーションをあなたと議論したいと思います。
Memcached & Redisのようなキャッシュはなぜ発明され、なぜ繁栄するのか?
キャッシュレイヤーは、リレーショナルデータベースから直接必要なデータを読み取るのにアプリケーションが遅すぎるため導入されました。
これは、Oracle、DB2、Postgres、MySQLなどで働くスマートな開発者がいないことを意味しますか? なぜこれらの開発者はリレーショナルデータベースを迅速に作成できないのでしょうか? その答えは、すべてのデータベースは、インデックス、内部データベースキャッシュ、およびその他の機能を含む偉大な開発者によって書かれたものであり、レコードの読み取りをできるだけ速くするための機能です。
問題は、アプリケーションが標準化された関係データベースから単一のレコードだけを読み取る必要がほとんどないことである。代わりに、通常は複数のテーブルで複数の Joins を実行して単一のビジネスオブジェクトを形成する必要があります。これらの Joins は高価です(それらは遅く、多くのリソースを消費します)。
ほとんどの関係データベースは、企業がデータベースとすべてのアプリケーションを単一のデータセンターで実行するようになった50年前に設計されました。今日は、企業と顧客が世界中に広がり、誰もが同じデータで作業したいとしています。
リレーショナルデータベースは、このデータ配布要件を考慮して設計されていません。RDBMS ベンダーは、さまざまなソリューションを試みて、これを取り巻くようにしましたが、これらは最適ではありません。
Redis と Memcached は、継続性が要求されていない Web アプリケーションのセッション処理に広く使用されていることに注意してください. その場合、キャッシュは、アプリケーションと MongoDB の間の唯一のデータストア (すなわち、キャッシュ レイヤーではありません) です。
では、Caching Tierを持つことの何が悪いのでしょうか。
キャッシュ レイヤーを導入することは、データベースがアプリケーションが必要とするパフォーマンスと遅延を提供できない場合に、しばしば素晴らしいソリューションです。
しかし、この追加のデータレベルにはコストが伴います. 明らかなものは、キャッシュサービスを提供するために必要なソフトウェアライセンスとハードウェアです.
より明らかなのは、開発者に課せられる余分な負担です。それは新しいクエリ言語(およびおそらくプログラミング言語)です。RDBMSのデータが変わるときに何が起こりますか?これらの変更はどのようにしてキャッシュレベルに広がりますか?
したがって、キャッシュ レベルは、アプリケーションがデータベースに直接アクセスすることにより、実質的な利点を提供することによって支払わなければなりません。
MongoDBとは何が違うの?
MongoDB ドキュメントモデル
MongoDB では、アプリケーションの最も頻繁なクエリ (または最も厳しい SLA を持つクエリ) を迅速に満たすのに効率的な方法でデータを構造化して保存するようにします。MongoDB は、単一のレコード (ドキュメント) に埋め込まれた (ネスト) オブジェクトを含むようにすることによって、オブジェクトの構造を反映します。
多くの場合、アプリケーションが要求するビジネスオブジェクトは、単一の MongoDB ドキュメントにマッピングされます。
MongoDB には独自の内部 LRU (最も最近使用された) キャッシュがありますので、ドキュメントが最近アクセスされた場合、それはすでにメモリにあります。
MongoDB がサポートされていることに注意してください。
キャッシュ レイヤーからのもう一つの付加価値は、分散アーキテクチャにおけるデータローカリゼーションです。
AIは何を考えているのか。
生成型AIによって生成された反応は、実際の人々によって公開された情報に基づいており、そのため、話題に関する一般的な意見を表すべきであると考えました。
ChatGPT 4o にこの質問をしました。
「なぜ、私のアプリケーションがMongoDBからのデータを直接読むよりも、キャッシュレイヤー(Redisなど)を使用するのか説明してください。
Redis は完全にメモリで動作し、データ回収のためにディスク I/O に依存する MongoDB よりも大幅に速くなります。
「なぜ、私のアプリケーションがMongoDBからのデータを直接読むよりも、キャッシュレイヤー(Redisなど)を使用するのか説明してください。
Redis は完全にメモリで動作し、データ回収のためにディスク I/O に依存する MongoDB よりも大幅に速くなります。
上記のように、MongoDB には独自のメモリキャッシュがあり、頻繁にアクセスするドキュメントはメモリにあり、ディスクへのアクセスは必要ありません。
「MongoDBの負荷を減らす. 同じデータのためのMongoDBに頻繁にアクセスすると、クエリの負荷が増加し、データベースを遅らせることができ、特に重い読み込みトラフィックの下で」
「MongoDBの負荷を減らす. 同じデータのためのMongoDBに頻繁にアクセスすると、クエリの負荷が増加し、データベースを遅らせることができ、特に重い読み込みトラフィックの下で」
MongoDB はスケーラブルです. Extra secondary nodes can be added to the replica set to add extra query bandwidth. MongoDB はスケーラブルです。
“High-Reading Traffic. Applications with high read-to-writing ratios (e.g., web apps, APIs) benefit from Redis’s ability to serve cached data quickly.”
“High-Reading Traffic. Applications with high read-to-writing ratios (e.g., web apps, APIs) benefit from Redis’s ability to serve cached data quickly.”
MongoDBのデータベースキャッシュは、データの変更を同期するための追加の開発者の努力なしに、同じ利点を提供します。
Redis は、頻繁にアクセスするまたはホットなデータ (たとえば、ユーザーセッション、構成、または製品の詳細) をキャッシュするのに最適です。
Redis は、頻繁にアクセスするまたはホットなデータ (たとえば、ユーザーセッション、構成、または製品の詳細) をキャッシュするのに最適です。
頻繁にアクセスするホットデータは、MongoDBのメモリ内のデータベースキャッシュに保管されます。
「地理分散アプリケーションの遅延を低減する. Redis キャッシュをエンドユーザーに近づけることで、遠隔地から MongoDB をクエリする際のネットワーク遅延を避けることができます。
「地理分散アプリケーションの遅延を低減する. Redis キャッシュをエンドユーザーに近づけることで、遠隔地から MongoDB をクエリする際のネットワーク遅延を避けることができます。
データロケーションは、アプリケーションサーバーのサイトの近くにレプリカを配置することによって解決できます。
"Support for Expiring Data (TTL) Redis には、指定された期間後にキャッシュされたデータを自動的に削除するタイム・トゥ・ライヴ(TTL)機能が組み込まれています。
"Support for Expiring Data (TTL) Redis には、指定された期間後にキャッシュされたデータを自動的に削除するタイム・トゥ・ライヴ(TTL)機能が組み込まれています。
MongoDB は LRU キャッシュを使用するため、リクエストされていない文書は、最近リクエストされたデータのためのスペースが必要な場合、メモリから削除されます。
MongoDB から繰り返し読むことは、特に複雑なクエリの場合、リソース密集で、インフラコストの増加につながる可能性があります。
MongoDB から繰り返し読むことは、特に複雑なクエリの場合、リソース密集で、インフラコストの増加につながる可能性があります。
あなたの MongoDB スケジュールは、重要なクエリが複雑なクエリを必要としないように設計する必要があります。
"Use Cases for Specialized Data Structures. Redis は、MongoDB がネイティブに提供していないリスト、セット、分類セット、ハッシュ、およびストリームなどの高度なデータ構造をサポートします。
"Use Cases for Specialized Data Structures. Redis は、MongoDB がネイティブに提供していないリスト、セット、分類セット、ハッシュ、およびストリームなどの高度なデータ構造をサポートします。
MongoDB はリストとセットをサポートしています. Hashes can be represented in MongoDB as an array of documents containing key-value pairs (キー値のカップル)
“Resilience and Fault Tolerance. A cache layer can serve as a fallback if MongoDB is temporarily unavailable or under heavy load.”
“Resilience and Fault Tolerance. A cache layer can serve as a fallback if MongoDB is temporarily unavailable or under heavy load.”
MongoDB は、任意のロード要件を満たすために垂直または水平にスケールできます。
“Simplified Complex Query Results. MongoDB は、頻繁にリクエストされる結果のために複雑なクエリ (たとえば、集計、 joins) を計算するのに時間がかかる可能性があります。
“Simplified Complex Query Results. MongoDB は、頻繁にリクエストされる結果のために複雑なクエリ (たとえば、集計、 joins) を計算するのに時間がかかる可能性があります。
あなたの MongoDB スケジュールは、複雑なクエリを頻繁に実行する必要を避けるように設計されなければなりません。
ChatGPT から得られる答えが、質問によって大きく歪んでいると注意してください. もし私が「Cache layer (such as Redis) を使うべきではなく、MongoDB から直接データを読み取るべきである理由を説明する」と質問するなら、ChatGPT は、Cache layer を追加するのを妨げ、システムの複雑性の増加、データの一貫性の問題、書き込みの重いワークロードのパフォーマンス、コスト、クエリの柔軟性、メンテナンスと信頼性、小さなデータセット(アクティブなデータセットが MongoDB のキャッシュに適合する)およびリアルタイムのレポートなどの問題を引用します。
概要
キャッシュ レイヤーは、あなたの RDBMS がアプリケーションが要求するクエリパフォーマンスを提供できない場合に多くの価値を追加できます。MongoDB を使用すると、レコードとキャッシュ機能のデータベースが 1 つのレイヤーに組み合わされ、お金と開発者の時間を節約します。
配布されたキャッシュは RDBMS の欠陥を軽減できますが、MongoDB には内蔵配布があります。
あなたのアプリケーションがあなたのアプリケーションとMongoDBの間のキャッシュレイヤーから恩恵を受けると思っている場合は、この記事に回答してください。
MongoDB デザインレビューについてもっと知る
この記事では、アプリケーションがデータでどのように動作するかと一致するMongoDBスケジュールを設計する場合、キャッシュレイヤーを必要とせずにパフォーマンス要件を満たすことができます。
あなたのアプリケーションはレビューから恩恵を受けるだろうか。