読み取りと書き込みの高速化: キャッシュは通常、フルメモリであるため( (例: Redis、Memcache)、ストレージ層 (MySQL など) は通常、読み取りおよび書き込みのパフォーマンスが高くなく、メモリの読み取りおよび書き込み速度はディスク I/O よりもはるかに高速です。キャッシュを使用すると、読み取りと書き込みが効果的に高速化され、ユーザー エクスペリエンスが最適化されます。
バックエンドの負荷を減らす: バックエンドがアクセスを減らすのを支援します (大量のアクセスが上限に達した場合、Mysql には最大接続数が設定されています)速度が非常に遅いため、接続の最大数がすぐに使い果たされてしまう可能性がありますが、Redis の理論上の最大数)、複雑な計算 (非常に複雑な SQL ステートメントなど) により負荷が軽減されます。バックエンドに大きく影響します。
データの不整合: キャッシュ層とストレージ層のデータは、特定の範囲内で不整合です。タイム ウィンドウ タイム ウィンドウは更新戦略に関連します。
コード保守コスト: キャッシュ追加後、キャッシュ層とストレージ層のロジックを同時に処理する必要があり、コストが増加します開発者のためにコードを保守すること。
運用保守コスト: Redis Cluster を例に挙げると、参加後は実質的に運用保守コストが増加します。
高オーバーヘッドを伴う複雑な計算: MySQL を例として、いくつかの複雑な操作または計算を取り上げます。 (たとえば、大量の結合テーブル操作や一部のグループ化計算など)、キャッシュを追加しないと、高い同時実行性を満たせないだけでなく、MySQL に大きな負担がかかります。
リクエスト応答の高速化: 単一のバックエンド データのクエリが十分に高速である場合でも、キャッシュを使用できます。Redis を例にとると、数万1 秒あたりに完了できる読み取りの数。書き込みおよび提供されるバッチ操作により、IO チェーン全体の応答時間を最適化できます。
考え方: 本番環境の Redis では、一部のデータが失われることが多く、一度書き込まれたデータは、しばらくすると失われる可能性があります。理由は何ですか?
通常、Redis キャッシュはメモリに保存されますが、メモリは貴重で有限であることを考慮して、ストレージには安価で大容量のディスクを使用するのが一般的です。マシンには数十ギガバイトのメモリしか搭載されていない場合がありますが、ハード ドライブの容量は数テラバイトである場合があります。 Redis は主にメモリに基づいて、高性能で同時実行性の高い読み取りおよび書き込み操作を実行します。では、メモリには制限があるため、たとえば、redis は 10G しか使用できませんが、20G のデータをそこに書き込む場合はどうしますか?もちろん、10Gのデータは削除され、その後10Gのデータは保持されます。どのようなデータを削除する必要がありますか?どのようなデータを保持する必要がありますか?当然のことながら、使用頻度の低いデータは削除し、頻繁に使用するデータは保持する必要があります。 Redis の有効期限ポリシーでは、データの有効期限が切れた場合でもメモリを占有し続けることが決定されます。
Redis では、使用メモリが maxmemory の上限 (used_memory > maxmemory) に達すると、対応するオーバーフロー制御ポリシーがトリガーされます。特定のポリシーは、maxmemory-policy パラメーターによって制御されます。
Redis は 6 つの戦略をサポートします:
noeviction: デフォルトの戦略、データは削除されず、すべての書き込み操作は拒否され、クライアント エラー メッセージ (エラー) メモリを使用している場合、OOM コマンドは許可されません。現時点では、Redis は読み取り操作のみに応答します
LRU アルゴリズムに従って、タイムアウト属性 (期限切れ) にして十分なスペースを解放します。削除可能なキー オブジェクトがない場合は、noeviction 戦略に戻ります
volatile-random: 十分なスペースが解放されるまで期限切れのキーをランダムに削除します
allkeys-lru: データにタイムアウト属性が設定されているかどうかに関係なく、十分なスペースが確保されるまで、LRU アルゴリズムに従ってキーを削除します。
allkeys-random: すべてのキーをランダムに削除します。十分なスペースが利用可能になるまで 十分なスペースが確保されるまで (推奨されません)
volatile-ttl: ttl (存続時間、TTL) 属性に基づいて、最も最近期限切れになったデータを削除します。キーと値のオブジェクト。そうでない場合は、noeviction 戦略に戻ります。
Redis サーバーで採用される有効期限戦略は次のとおりです: 遅延削除 定期的な削除
遅延削除:各 Redis ライブラリには、すべてのキーの有効期限を節約する有効期限ディクショナリが含まれています。クライアントがキーを読み取るとき、最初に有効期限ディクショナリでキーの有効期限が切れているかどうかを確認し、キーの有効期限が切れている場合は、削除操作を実行して空を返します。この戦略は CPU コストを節約するためのものですが、この方法だけを使用するとメモリ リークの問題が発生し、期限切れのキーにアクセスしないと削除が間に合わず、メモリの解放が間に合わなくなります。
スケジュールされた削除:
Redis はスケジュールされたタスクを内部的に維持し、デフォルトで 1 秒あたり 10 回の有効期限スキャンを実行します (redis.conf の hz 構成によって変更されます)。回)、スキャンは期限切れの辞書内のすべてのキーを走査するわけではありませんが、適応アルゴリズムを使用して、高速と低速の 2 つのレート モードを使用してキーの有効期限率に基づいてキーをリサイクルします:
1。期限切れの辞書 20 個のキーを取り出します
2. これら 20 個のキーのうち期限切れのキーを削除します
3. 期限切れのキーの割合が 25% を超える場合は、手順 1 と 2
を繰り返して、スキャンでループが発生しません 過度に、スケジュールされた削除スケジュールされたタスクを実行しているため、外部にサービスを提供できず、スレッドがスタックします。また、スキャン時間の上限も増加します。デフォルトは 25 ミリ秒 (つまり、デフォルトは低速モードです。25 ミリ秒が完了していない場合は、ブロック モードに切り替えます。モードのタイムアウト時間は 1 ミリ秒で、2 秒以内に 1 回だけ実行できます。低速モードが完了して正常に終了すると、 、高速モードに戻ります)
1. アプリケーションは最初にキャッシュからデータを取得します。取得できなかった場合は、データベースからデータを取得し、成功するとキャッシュに格納します。
2. まずキャッシュを削除してからデータベースを更新します: この操作には大きな問題があります。キャッシュを削除した後、データの更新リクエストは読み取りリクエストを受け取ります。このとき、キャッシュは削除されているため、 、読み取りリクエストは直接読み取られます。ライブラリ、読み取り操作のデータは古いため、キャッシュにロードされます。後続の読み取りリクエストはすべての古いデータにアクセスします。
3. まずデータベースを更新してからキャッシュを削除します (推奨) データベースに書き込んだ後にキャッシュを更新してみてはいかがでしょうか?主な理由は、2 つの同時書き込み操作がダーティ データを引き起こす可能性があることです。
すべてのデータをキャッシュすることは、部分的なデータよりも汎用性が高くなりますが、実際の経験から、アプリケーションは長期間必要とするのは少数の重要なデータのみです。プロパティ。
すべてのデータをキャッシュすると、データの一部よりも多くのスペースが占有されます。次の問題があります:
すべてのデータにより、次のような問題が発生します。記憶障害の無駄。
すべてのデータは、送信されるたびに大量のネットワーク トラフィックが発生し、比較的長い時間がかかり、極端な場合にはネットワークがブロックされる可能性があります。
すべてのデータのシリアル化と逆シリアル化の CPU オーバーヘッドが大きくなります。
完全なデータには明らかな利点がありますが、一部のデータに新しいフィールドを追加する場合は、ビジネス コードを変更し、通常はコードを更新する必要があります。キャッシュデータ。 。
以上がRedis キャッシュ更新戦略とは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。