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