通常は、データベースアクセスの負担を軽減するために、Redisキャッシュの使用を優先します。ただし、多数のユーザーがシステムにアクセスすると、まずキャッシュにクエリが実行され、キャッシュにデータがない場合はデータベースにクエリが実行され、その後、データがキャッシュに更新されます。 、データベース内のデータが変更された場合は、redis に同期する必要があります。同期プロセス中、MySQL と redis の間のデータの一貫性を確保する必要があります。この同期プロセス中に短いデータ遅延が発生するのは通常のことです。ただし、最終的には、mysql とキャッシュの間の一貫性を確保する必要があります。
//我们通常使用redis的逻辑 //通常我们是先查询reids String value = RedisUtils.get(key); if (!StringUtils.isEmpty(value)){ return value; } //从数据库中获取数据 value = getValueForDb(key); if (!StringUtils.isEmpty(value)){ RedisUtils.set(key,value); return value; }
遅延二重削除戦略は、分散システムで一貫性を維持するためのデータベース ストレージとキャッシュ データの一般的な戦略ですが、強力な一貫性はありません。実際、どのソリューションを使用しても、Redis のダーティ データの問題は回避できません。この問題を軽減することしかできません。この問題を完全に解決するには、同期ロックと対応するビジネス ロジック レベルを使用して解決する必要があります。
通常、データベース データを更新するときは、redis にキャッシュされたデータを同期する必要があるため、通常 2 つの解決策があります:
最初の解決策: 最初の更新操作を実行します。を選択し、キャッシュクリアを実行します。
2 番目のオプション: 最初にキャッシュのクリアを実行してから、更新操作を実行します。
ただし、これら 2 つのソリューションでは、同時リクエストで次の問題が発生する傾向があります。
最初のソリューションの欠点: リクエスト 1 の場合データベースの更新操作が実行された後、キャッシュのクリアが実行される前に、リクエスト 2 が入ってキャッシュをクエリします。この時点では、キャッシュ内のデータはまだ古いデータであり、削除される前に削除されていません。により、データの問題が発生します。ただし、t1 がキャッシュ削除操作を実行した後は、後続のリクエストでキャッシュのクエリ、データのクエリ、キャッシュへの更新ができなくなります。この影響は比較的小さいです。
t1 スレッドが最初にデータベースを更新します;
t2 スレッド クエリがキャッシュにヒットし、古いデータを返します;
t1 スレッドがデータベースを更新しました。キャッシュ キーは 5 ミリ秒以内に削除され、他のスレッドは 5 ミリ秒以内にクエリを実行すると予想されます。キャッシュされた結果は古いデータのままですが、クエリのキャッシュされた結果は 5 ミリ秒後には空になります。最新の DB 結果が Redis に再度同期されます。
プロジェクトに遅延が発生するのはよくあることなので、そのような遅延がビジネスに与える影響は実際には非常に限定的です。しかし、それが発生してキャッシュの削除に失敗した場合はどうなるでしょうか?
1. 再試行を続ける ----http プロトコル インターフェイスにある場合、インターフェイスの応答が遅くなり、このインターフェイスを呼び出すときに応答タイムアウトが発生します。 mq 非同期形式による
2 番目の解決策の欠点: リクエスト 1 がキャッシュをクリアしてもデータ更新操作をまだ実行していない場合、リクエスト 2 が古いデータをクエリするために入ります。データベースと書き込み redis を入力すると、データベースと redis データの間で不整合の問題が発生します。
t1 スレッドは最初にキャッシュを削除します;
t2 スレッドはキャッシュを null として読み取り、db データをキャッシュに同期します;
t1 スレッドは db 内のデータを更新します;
t3 スレッドはキャッシュ内のデータが古いデータであることをクエリします;
更新操作を実行する前にキャッシュをクリアし、更新操作後に N 秒待ってキャッシュを再度クリアします。完成しました。 2 回の削除が実行され、一定の遅延が必要です
RedisUtils.del(key);// 先删除缓存 updateDB(user);// 更新db中的数据 Thread.sleep(N);// 延迟一段时间,在删除该缓存key RedisUtils.del(key);// 先删除缓存
上記の時間 (遅延 N 秒) は、書き込み操作の時間よりも長くなります。 redis への書き込み時間が遅延時間よりも早い場合、リクエスト 1 はキャッシュをクリアしますが、リクエスト 2 のキャッシュはまだ書き込まれていないため、厄介な状況が発生します。 。 。
業務プログラム実行時に、データの読み込みやキャッシュの書き込みなどのビジネスロジック実行の動作時間をもとに見積もります。 「遅延二重削除」は、このソリューションではキャッシュされた値を最初に削除した後、一定期間の遅延後に再度削除するためです。
以上がRedis の遅延二重削除戦略の使用方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。