キャッシュアバランチ#
キャッシュアバランチ:大量のキャッシュデータが同時に期限切れ(無効)になったり、Redis が故障してダウンした場合、その時に大量のユーザーリクエストがあり、Redis で処理できないと、これらのリクエストは直接データベースにアクセスし、データベースの負荷が急増し、深刻な場合はデータベースがクラッシュしてダウンし、システム全体がクラッシュすることになります。
解決策:
- 大量のデータに同じ期限を設定するのを避け、期限を設定する際にランダムな数値を追加することで、データが同時に期限切れにならないようにします。
- ミューテックスロック、アクセスするデータが Redis にないことがわかった場合、ミューテックスロックを追加し、同時に 1 つのリクエストだけがキャッシュを構築することを保証します(データベースからデータを読み取り、そのデータを Redis に更新します)。キャッシュの構築が完了したら、ロックを解除します。ミューテックスロックを取得できなかったリクエストは、ロックが解除されるのを待つか、空の値またはデフォルト値を直接返します。ミューテックスロックを実装する際には、タイムアウト時間を設定する必要があります。そうしないと、あるリクエストがロックを取得した後、リクエストが予期しない状況でブロックされ続け、ロックを解除しない場合、他のリクエストはロックを取得できず、システム全体が応答しなくなる現象が発生します。
- バックグラウンドでキャッシュを更新し、ビジネススレッドがキャッシュの更新を担当せず、キャッシュに有効期限を設定せず、キャッシュを「永久に有効」にし、キャッシュの更新作業をバックグラウンドスレッドに定期的に更新させます。
キャッシュブレイク#
キャッシュブレイク:キャッシュ内の特定のホットデータが期限切れになった場合、大量のリクエストがこれらのホットデータにアクセスしようとすると、キャッシュから読み取れず、直接データベースにアクセスすることになり、高い同時リクエストによってデータベースが崩壊します。
解決策:
- ミューテックスロック、同時に 1 つのスレッドだけがキャッシュを更新することを保証し、ミューテックスロックを取得できなかったリクエストは、ロックが解除されるのを待つか、空の値またはデフォルト値を直接返します。
- ホットデータに有効期限を設定せず、バックグラウンドで非同期にキャッシュを更新するか、ホットデータが期限切れになる前に、バックグラウンドスレッドにキャッシュを更新し、有効期限を再設定するように事前通知します。
キャッシュペネトレーション#
キャッシュペネトレーション:ユーザーがアクセスするデータがキャッシュにもデータベースにも存在しない場合、リクエストがキャッシュにアクセスする際に無効になり、データベースにアクセスしてもそのデータが存在しないことがわかり、キャッシュを構築して後続のリクエストにサービスを提供できません。このようなリクエストが大量にあると、データベースの負荷が急増し、データベースがクラッシュします。
解決策:
- 不正リクエストの判断:リクエストの入口でリクエストパラメータの検証を追加し、パラメータが合理的かつ有効かを確認します。不正なパラメータの場合は、直接エラーを返し、キャッシュやデータベースへのさらなるアクセスを避けます。
- 空の値またはデフォルト値をキャッシュする、特定のクエリ対象データに対して、キャッシュに空の値またはデフォルト値を設定し、後続のリクエストがキャッシュから空の値またはデフォルト値を直接読み取ってアプリケーションに返すことができるようにし、データベースをさらにクエリしないようにします。
- ブルームフィルター:ユーザーリクエストが到着した際に、ブルームフィルターを照会してデータの存在を迅速に判断できるようにし、存在しない場合はデータベースを再度照会する必要がなく、データベースが正常に動作することを保証します。