熱點(diǎn)緩存key重建優(yōu)化
開發(fā)人員使用“緩存+過期時間”的策略既可以加速數(shù)據(jù)讀寫, 又保證數(shù)據(jù)的定期更新, 這種模式基本能夠滿足絕大部分需求。 但是有兩個問題如果同時出現(xiàn), 可能就會對應(yīng)用造成致命的危害:
當(dāng)前key是一個熱點(diǎn)key(例如一個熱門的娛樂新聞),并發(fā)量非常大。
重建緩存不能在短時間完成, 可能是一個復(fù)雜計算, 例如復(fù)雜的SQL、 多次IO、 多個依賴等。
在緩存失效的瞬間, 有大量線程來重建緩存, 造成后端負(fù)載加大, 甚至可能會讓應(yīng)用崩潰。
要解決這個問題主要就是要避免大量線程同時重建緩存。
我們可以利用互斥鎖來解決,此方法只允許一個線程重建緩存, 其他線程等待重建緩存的線程執(zhí)行完, 重新從緩存獲取數(shù)據(jù)即可。
示例偽代碼:文章來源地址http://www.zghlxwxcb.cn/news/detail-845534.html
String get(String key) {
// 從Redis中獲取數(shù)據(jù)
String value = redis.get(key);
// 如果value為空, 則開始重構(gòu)緩存
if (value == null) {
// 只允許一個線程重建緩存, 使用nx, 并設(shè)置過期時間ex
String mutexKey = "mutext:key:" + key;
if (redis.set(mutexKey, "1", "ex 180", "nx")) {
// 從數(shù)據(jù)源獲取數(shù)據(jù)
value = db.get(key);
// 回寫Redis, 并設(shè)置過期時間
redis.setex(key, timeout, value);
// 刪除key_mutex
redis.delete(mutexKey);
}// 其他線程休息50毫秒后重試
else {
Thread.sleep(50);
get(key);
}
}
return value;
}
文章來源:http://www.zghlxwxcb.cn/news/detail-845534.html
到了這里,關(guān)于Redis緩存設(shè)計與性能優(yōu)化【并發(fā)創(chuàng)建同一個緩存,解決方案:互斥鎖】的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!