キャッシュスルーとキャッシュ雪崩が分かったので、キャッシュ破壊を理解してください!
キャッシュ破壊とキャッシュ雪崩の違いは、雪崩は多くのkeyに対して行われ、破壊はあるホットスポットkeyに対してのみ行われることである.
キャッシュが期限切れにならないように設定するには、暴力的ですが、ほとんどの問題を解決することができます.もちろん、ほとんどのシーンはあまり適用されません.
ランダムな期限切れを設定すると、このスキームはキャッシュの破壊にはあまり適用されません.破壊はホットスポットkeyに対してのみ行われ、それが失効すると、大量のアクセスがデータベースを破壊します.
残りのシナリオは、例えば、反発ロック、デュアルキャッシュメカニズムを使用しても、キャッシュ破壊の問題を解決することができます.これらのシナリオの具体的な実装を見てみましょう.
キャッシュのプロアクティブ・リフレッシュ
キャッシュは期限切れに設定されており、DBのデータを更新または削除する際にも、キャッシュのデータをアクティブに更新または削除します.
このスキームは容易に理解できるが、実装は複雑であるが、キャッシュを使用する必要があるデータは、デュアルライト・データベースとキャッシュのコードを増やす必要があり、デュアルライト・プロセスでは、データの一貫性を維持する必要がある.
更新の確認
キャッシュは依然として設定の期限切れ時間を維持し、getキャッシュのたびにデータの期限切れ時間と現在の時間と比較し、間隔時間がしきい値より小さい場合、キャッシュをアクティブに更新します.
たとえば(キャッシュの有効期限-現在のシステム時間)が5分未満の場合、キャッシュをリフレッシュし、キャッシュの有効期限をリセットします.
しかし、この方法には致命的な問題があります.データがキャッシュが無効になる5分前に1回のアクセスがなければ、チェック更新はトリガーされず、キャッシュが無効になった後に大量のアクセスが要求されると、キャッシュが破壊されます.
ロックの使用
キャッシュが無効になった後、反発ロックまたはキューによって、リード・データベースとライト・キャッシュのスレッド数を制御します.
第1の方法:全体の方法はsynchronizedで、このようにして大量の要求がDB上に落ちることを防止することができますが、キャッシュが失効していなくても、DBからデータを照会する必要があります.キューに並ぶ必要があります.システムのスループットを低下させることは間違いありません.
第2の方法:キャッシュが無効になった場合、クエリー・データベースの操作のみをロックすることで、キャッシュが無効になっていない場合にも非常に友好的ですが、クエリー・操作ここでロックをかけるのは、他の呼び出しをブロックするだけで、第1の他のスレッドは待たなければなりません.呼び出し側に友好的ではありません.第2のこれらの要求がブロックされた要求は最終的にDBに落ちます.
3つ目の方法は、反発ロックを使用して、ロックを奪うとデータベースを読み取りキャッシュに書き込み、ロックを奪うことができなければブロックせず、キャッシュを直接読み取り、キャッシュ中にデータが読めない場合(ロックを奪った場合、キャッシュを書き込み成功していない可能性があります)、後で読み取りキャッシュを試してみます.
デュアルキャッシュ
1つのキャッシュと2つのキャッシュを設定します.1つのキャッシュの有効期限が短く、2つのキャッシュの有効期限が長いか、有効期限が切れていないかを設定します.1つのキャッシュが無効になった後、2つのキャッシュにアクセスし、1つのキャッシュと2つのキャッシュをリフレッシュします.
ダブルキャッシュの方式は、はっきり言って、1級キャッシュと2級キャッシュの中のデータを同時に失効させることができなくて、1級キャッシュが失効した後、複数の要求アクセスがあって、互いに依然として競争ロックで、ロックのスレッドを奪ってデータベースを問合せてキャッシュをリフレッシュして、その他のロックを奪っていないスレッドは、図:
コードを注文するおじさん|文【オリジナル】
キャッシュが期限切れにならないように設定するには、暴力的ですが、ほとんどの問題を解決することができます.もちろん、ほとんどのシーンはあまり適用されません.
ランダムな期限切れを設定すると、このスキームはキャッシュの破壊にはあまり適用されません.破壊はホットスポットkeyに対してのみ行われ、それが失効すると、大量のアクセスがデータベースを破壊します.
残りのシナリオは、例えば、反発ロック、デュアルキャッシュメカニズムを使用しても、キャッシュ破壊の問題を解決することができます.これらのシナリオの具体的な実装を見てみましょう.
キャッシュのプロアクティブ・リフレッシュ
キャッシュは期限切れに設定されており、DBのデータを更新または削除する際にも、キャッシュのデータをアクティブに更新または削除します.
このスキームは容易に理解できるが、実装は複雑であるが、キャッシュを使用する必要があるデータは、デュアルライト・データベースとキャッシュのコードを増やす必要があり、デュアルライト・プロセスでは、データの一貫性を維持する必要がある.
更新の確認
キャッシュは依然として設定の期限切れ時間を維持し、getキャッシュのたびにデータの期限切れ時間と現在の時間と比較し、間隔時間がしきい値より小さい場合、キャッシュをアクティブに更新します.
たとえば(キャッシュの有効期限-現在のシステム時間)が5分未満の場合、キャッシュをリフレッシュし、キャッシュの有効期限をリセットします.
しかし、この方法には致命的な問題があります.データがキャッシュが無効になる5分前に1回のアクセスがなければ、チェック更新はトリガーされず、キャッシュが無効になった後に大量のアクセスが要求されると、キャッシュが破壊されます.
ロックの使用
キャッシュが無効になった後、反発ロックまたはキューによって、リード・データベースとライト・キャッシュのスレッド数を制御します.
第1の方法:全体の方法はsynchronizedで、このようにして大量の要求がDB上に落ちることを防止することができますが、キャッシュが失効していなくても、DBからデータを照会する必要があります.キューに並ぶ必要があります.システムのスループットを低下させることは間違いありません.
public synchronized String getCacheData() {
String cacheData = "";
// Redis
cacheData = getDataFromRedis();
if (cacheData.isEmpty()) {
//
cacheData = getDataFromDB();
// Redis
setDataToCache(cacheData);
}
return cacheData;
}
第2の方法:キャッシュが無効になった場合、クエリー・データベースの操作のみをロックすることで、キャッシュが無効になっていない場合にも非常に友好的ですが、クエリー・操作ここでロックをかけるのは、他の呼び出しをブロックするだけで、第1の他のスレッドは待たなければなりません.呼び出し側に友好的ではありません.第2のこれらの要求がブロックされた要求は最終的にDBに落ちます.
static Object lock = new Object();
public String getCacheData() {
String cacheData = "";
// Redis
cacheData = getDataFromRedis();
if (cacheData.isEmpty()) {
synchronized (lock) {
//
cacheData = getDataFromDB();
// Redis
setDataToCache(cacheData);
}
}
return cacheData;
}
3つ目の方法は、反発ロックを使用して、ロックを奪うとデータベースを読み取りキャッシュに書き込み、ロックを奪うことができなければブロックせず、キャッシュを直接読み取り、キャッシュ中にデータが読めない場合(ロックを奪った場合、キャッシュを書き込み成功していない可能性があります)、後で読み取りキャッシュを試してみます.
public String getCacheData(){
String result = "";
// Redis
result = getDataFromRedis();
if (result.isEmpty()) {
if (reenLock.tryLock()) {
try {
//
result = getDataFromDB();
// Redis
setDataToCache(result);
}catch(Exception e){
//...
}finally {
reenLock.unlock();//
}
} else {
// : :
//
// Redis
result = getDataFromRedis();
if (result.isEmpty()) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
//...
}
return getCacheData();
}
}
}
return result;
}
デュアルキャッシュ
1つのキャッシュと2つのキャッシュを設定します.1つのキャッシュの有効期限が短く、2つのキャッシュの有効期限が長いか、有効期限が切れていないかを設定します.1つのキャッシュが無効になった後、2つのキャッシュにアクセスし、1つのキャッシュと2つのキャッシュをリフレッシュします.
ダブルキャッシュの方式は、はっきり言って、1級キャッシュと2級キャッシュの中のデータを同時に失効させることができなくて、1級キャッシュが失効した後、複数の要求アクセスがあって、互いに依然として競争ロックで、ロックのスレッドを奪ってデータベースを問合せてキャッシュをリフレッシュして、その他のロックを奪っていないスレッドは、図:
コードを注文するおじさん|文【オリジナル】