今日は、キャッシュの世界に飛び込みます。キャッシュは、スケーラブルで高性能なシステムを構築するための秘密兵器です。キャッシュには多くの種類がありますが、この記事では、バックエンド オブジェクト キャッシュ (バックエンド キャッシュ) に焦点を当てます。これをマスターすると、高性能で信頼性の高いソフトウェアを構築するのに役立ちます。 この記事では、次の内容について説明します。 キャッシュについて説明し、アクセスを高速化するためにデータを一時的に保存する方法について説明します。 キャッシュとは何ですか? : キャッシュによって速度が向上し、サーバーの負荷が軽減され、ユーザー エクスペリエンスが向上し、コストも削減される仕組みについて説明します。 キャッシュの利点 : このセクションでは、キャッシュを使用するさまざまな方法について詳しく説明します。それぞれのアプローチには長所と短所があるので、ニーズに合った適切なパターンを選択するようにしてください。 キャッシュ パターン : キャッシュされたデータを保存および取得する方法はわかりました。しかし、キャッシュされたデータが最新の状態に保たれるようにするにはどうすればよいでしょうか。また、キャッシュの容量がいっぱいになるとどうなるでしょうか。 キャッシュのベスト プラクティス : キャッシュには多くの利点がありますが、避けた方が良い場合もあります。間違ったシステムにキャッシュを実装すると、複雑さが増し、パフォーマンスが低下する可能性もあります。 キャッシュしない方が良い場合 キャッシュとは何ですか? 高性能でスケーラブルなアプリケーションを作成するには、ボトルネックを解消し、システムの効率を高めることが重要です。データベースは、ストレージと処理の要件により、システム パフォーマンスのボトルネックになることがよくあります。データベースは頻繁にスケールアップする必要があるため、コストのかかるコンポーネントになります。 幸いなことに、データ取得速度を向上させながらデータベース リソースの使用負荷を軽減できるコンポーネントがあります。このコンポーネントは、 と呼ばれます。 キャッシュ キャッシュは、データの高速な書き込みと読み取りのために設計された一時ストレージです。低レイテンシのメモリ ストレージと最適化されたデータ構造を使用して、迅速な操作を実現します。おそらく、Redis または Memcached をすでに使用したことがあるか、少なくともその名前を聞いたことがあるでしょう。これらは、バックエンド サービスで最も人気のある 2 つの分散キャッシュ システムです。Redis はプライマリ データベースとしても機能しますが、これは別の記事で取り上げます。 キャッシュの利点 キャッシュの主な利点は、その速度です。キャッシュからデータを読み取ると、データベース (SQL や Mongo など) からデータを取得するよりも大幅に高速になります。この速度は、キャッシュが辞書 (または HashMap) データ構造を使用して高速操作を行い、データをディスクではなく高速メモリに保存することで実現されます。 2 番目に、キャッシュによりデータベースの負荷が軽減されます。これにより、アプリケーションはデータベースに頻繁にアクセスする代わりに、必要なデータをキャッシュから取得できます。これによりハードウェア リソースの使用量が劇的に減少します。システムはディスク上のデータを検索する代わりに、高速メモリからデータにアクセスするだけです。 これらの利点は、ユーザー エクスペリエンスを直接向上させ、コスト削減につながります。アプリケーションの応答速度が大幅に向上し、ユーザーにとってよりスムーズで満足度の高いエクスペリエンスが実現します。 キャッシュによりインフラストラクチャ コストが削減されます。Redis のような分散システムには独自のリソースが必要ですが、全体的な節約は多くの場合、大幅になります。アプリケーションはより効率的にデータにアクセスし、データベースを縮小できる可能性があります。ただし、これにはトレードオフが伴います。キャッシュ システムに障害が発生した場合、データベースが負荷の増加に対応できる準備ができていることを確認してください。 キャッシュパターン キャッシュの威力がわかったところで、次はキャッシュの最適な使用方法について見ていきましょう。このセクションでは、 と という 2 つの重要なパターン カテゴリについて説明します。これらのパターンは、キャッシュ更新を管理し、必要なデータがまだキャッシュにない場合に状況に対処するための戦略を提供します。 キャッシュ書き込みパターン キャッシュ ミス パターン ライティングパターン 書き込みパターンは、アプリケーションがキャッシュとデータベースの両方とどのようにやり取りするかを決定します。ここでは 、 、 という 3 つの一般的な戦略について見てみましょう。それぞれに独自の利点とトレードオフがあります。 、 ライトバック ライトスルー ライトアラウンド 返事を書く 使い方: アプリケーションはキャッシュとのみ対話します。 キャッシュは書き込みを即座に確認します。 次に、バックグラウンド プロセスによって新しく書き込まれたデータがデータベースにコピーされます。 書き込み量が多く、速度が重要で、パフォーマンスのために多少の不整合が許容されるアプリケーション。例としては、メトリックや分析アプリケーションなどがあります。 最適な用途: 利点: データは常にキャッシュ内にあるため、データベースを完全にバイパスして、すばやくアクセスできます。 読み取り速度が速くなります: アプリケーションはデータベースへの書き込みを待機しないため、応答時間が短縮されます。 書き込みの高速化: バッチ書き込みによりデータベースの負荷が軽減され、データベース ハードウェアの寿命が延びる可能性があります。 データベースの負担が軽減: デメリット: データがデータベースに保存される前にキャッシュに障害が発生すると、情報が失われる可能性があります。Redis は永続的なストレージによってこのリスクを軽減しますが、複雑さが増します。 データ損失のリスク: キャッシュとデータベースが最終的に同期された状態を保つためにミドルウェアが必要になります。 複雑さが増す: データが頻繁に読み取られない場合でも、すべての書き込みは最初にキャッシュに送られます。これにより、ストレージの消費量が高くなる可能性があります。 キャッシュ使用率が高くなる可能性: ライトスルー 使い方: アプリケーションはキャッシュとデータベースの両方に同時に書き込みます。 待機時間を短縮するには、キャッシュに非同期で書き込むことができます。これにより、アプリケーションはキャッシュ操作が完全に終了する前に書き込みが成功したことを通知できます。 利点: ライトバックと同様に、データは常にキャッシュ内にあるため、データベースの読み取りが不要になります。 読み取り速度の向上: アプリケーションは、書き込みがデータベースに保存された後にのみ書き込みを確認するため、直後にクラッシュが発生した場合でもデータの永続性が保証されます。 信頼性: デメリット: ライトバックと比較すると、このポリシーでは、アプリケーションがデータベースとキャッシュの両方の書き込みを待機するため、オーバーヘッドが発生します。非同期書き込みにより、このオーバーヘッドは改善されますが、データベースの待機時間は常に存在することに注意してください。 書き込み速度が遅い: すべての書き込みはキャッシュに送られるため、データに頻繁にアクセスされない場合でもストレージが消費される可能性があります。 キャッシュ使用率が高い: 書き回す ライトアラウンドを使用すると、アプリケーションは書き込みプロセス中にキャッシュをバイパスして、データベースに直接データを書き込みます。キャッシュにデータを入力するには、 と呼ばれる戦略を採用します。 キャッシュアサイド パターン アプリケーションはキャッシュをチェックします。 読み取り要求が到着: データがキャッシュ内に見つからない場合、アプリケーションはデータベースからデータを取得し、将来使用するためにキャッシュに保存します。 キャッシュ ミス: 利点: データはデータベースに直接書き込まれるため、一貫性が確保されます。 信頼性の高い書き込み: 頻繁にアクセスされるデータのみがキャッシュされるため、メモリの消費量が削減されます。 効率的なキャッシュ使用: デメリット: データがキャッシュ内にない場合、アプリケーションはデータベースからデータを取得する必要があり、キャッシュが常に事前に設定されているポリシーと比較してラウンドトリップが増加します。 読み取り待ち時間が長くなる (場合によっては): キャッシュミスパターン キャッシュ ミスは、アプリケーションに必要なデータがキャッシュ内に見つからない場合に発生します。これに対処するための一般的な戦略を 2 つ紹介します。 キャッシュアサイド アプリケーションはキャッシュをチェックします。 ミスが発生した場合は、データベースからデータを取得してキャッシュを更新します。 キャッシュの管理はアプリケーションが担当します。 重要なポイント: キャッシュアサイドパターンを使用すると、アプリケーションがキャッシュを管理することになります。このアプローチはシンプルで、アプリケーション以外の場所での開発を必要としないため、最も一般的に使用されています。 読み通し アプリケーションはキャッシュを認識せずにリクエストを行います。 特殊なメカニズムがキャッシュをチェックし、必要に応じてデータベースからデータを取得します。 キャッシュは透過的に更新されます。 リードスルー パターンはアプリケーションの複雑さを軽減しますが、インフラストラクチャの複雑さは増大します。代わりに、アプリケーション リソースをミドルウェアにオフロードすると役立ちます。 全体的に、キャッシュアサイドを使用したライトアラウンド パターンは、実装が簡単なため、最も一般的に使用されています。ただし、キャッシュされた直後に使用されるデータがある場合は、ライトスルー パターンも含めることをお勧めします。これにより、読み取りパフォーマンスがわずかに向上します。 キャッシュのベストプラクティス このセクションでは、キャッシュの使用に関するベスト プラクティスについて説明します。これらのベスト プラクティスに従うことで、キャッシュが最新のデータを維持し、ストレージを効果的に管理できるようになります。 キャッシュの無効化 キャッシュにデータを保存し、その後データベースが更新されたとします。これにより、キャッシュ内のデータがデータベースのバージョンと異なることになります。このタイプのキャッシュ データを「古い」と呼びます。キャッシュ無効化技術がないと、データベースの更新後もキャッシュされたデータが古いままになる可能性があります。データを最新の状態に保つには、次の技術を使用できます。 データベース内のデータを更新する場合は、対応するキャッシュ エントリも更新します。ライトスルー パターンとライトバック パターンは本質的にこれを処理しますが、ライトアラウンド/キャッシュアサイドではキャッシュされたデータを明示的に削除する必要があります。この戦略により、アプリケーションが古いデータを取得するのを防ぐことができます。 更新時のキャッシュ無効化: TTL は、キャッシュにデータを保存するときに設定できるポリシーです。TTL を使用すると、指定された時間が経過するとデータが自動的に削除されます。これにより、未使用のデータが消去され、無効化が失敗した場合に古いデータに対するフェイルセーフが提供されます。 Time To Live (TTL): キャッシュ置換ポリシー 大量のデータをキャッシュすると、キャッシュ ストレージがいっぱいになる可能性があります。キャッシュ システムは通常、メモリを使用しますが、そのメモリはプライマリ データベース ストレージよりも小さいことがよくあります。キャッシュがいっぱいになると、スペースを確保するために一部のデータを削除する必要があります。キャッシュ置換ポリシーによって、削除するデータが決定されます。 この一般的なポリシーは、最も長い間使用されていないデータ (読み取りまたは書き込み) を削除します。LRU は、ほとんどの実際の使用例に適しています。 最も長い間使用されていないデータ (LRU): LRU に似ていますが、アクセス頻度に重点を置いています。新しく書き込まれたデータは削除される可能性があるため、データを削除できないウォームアップ期間を追加することを検討してください。 最も使用頻度の低いデータ (LFU): FIFO (先入先出法)、ランダム交換などの他の交換ポリシーも存在しますが、あまり一般的ではありません。 キャッシュしない方が良い場合 キャッシュの実装に踏み込む前に、キャッシュが最適では 可能性がある場合を知っておくことが重要です。キャッシュは多くの場合、速度を向上させ、データベースの負荷を軽減しますが、次の場合には意味がない可能性があります。 ない アプリケーションのトラフィックが少なく、応答時間がまだ許容範囲内である場合は、まだキャッシュは必要ありません。キャッシュを追加すると複雑さが増すため、パフォーマンスのボトルネックが発生した場合やトラフィックの大幅な増加が予想される場合に実装するのが最適です。 トラフィックが少ない: キャッシュは、読み取りが大量なアプリケーションで最も効果的です。つまり、データベース内のデータは頻繁に更新されないか、更新の合間に複数回読み取られます。アプリケーションの書き込み量が多い場合、キャッシュによってオーバーヘッドが増加し、速度が低下する可能性があります。 システムの書き込みが大量である場合: まとめ この記事では、キャッシュの基本と効果的な使用方法について説明しました。重要なポイントをまとめると次のようになります。 システムの読み取り負荷が高く、キャッシュが提供するレイテンシ削減が必要であることを確認します。 必要性を確認する: アプリケーションがデータを使用する方法に合わせて、キャッシュ書き込みとキャッシュ ミスのパターンを選択します。 パターンを賢く選択する: 古いデータの提供を防ぐために、キャッシュ無効化戦略を実装します。 データの鮮度: キャッシュが容量に達したときに削除を処理するためのキャッシュ置換ポリシー (LRU など) を選択します。 置換ポリシーの管理: 参考文献 https://gist.github.com/jboner/2841832 https://www.bytesizedpieces.com/posts/cache-types https://www.techtarget.com/searchstorage/definition/cache https://www.youtube.com/watch?v=dGAgxozNWFE