背景
關于緩存異常,我們常見的有三個問題:緩存雪崩、緩存擊穿、緩存穿透。這三個問題一旦發(fā)生,會導致大量請求直接落到數(shù)據庫層面。如果請求的并發(fā)量很大,會影響數(shù)據庫的運行,嚴重的會導致數(shù)據庫宕機。
為了避免緩存異常帶來的損失,我們需要了解每種異常的原因以及解決方案,提高系統(tǒng)的可靠性
緩存雪崩
原因:同一時間緩存中的數(shù)據大面積過期或者Redis 緩存實例發(fā)生故障宕機
- 解決方案:對于不同key設置不同的過期時間、搭建集群防止宕機
緩存擊穿
緩存雪崩是因為大面積的緩存失效,打崩了數(shù)據庫。而緩存擊穿是指某個訪問非常頻繁的熱點數(shù)據,大量并發(fā)請求集中在這一個點訪問,在這個Key失效的瞬間,持續(xù)的大并發(fā)就穿破緩存,直接請求數(shù)據庫,就像在一個屏障上鑿了一個洞
- 解決方案
- 設置熱點數(shù)據永不過期:不設置失效時間,有更新的話,需要更新緩存;
- 加互斥鎖:單機可以使用synchronized、lock,分布式可以使用lua腳本
緩存穿透
緩存穿透指用戶要訪問的數(shù)據既不在緩存中也不在數(shù)據庫中,導致用戶每次請求該數(shù)據時都要去數(shù)據庫查一遍,然后返回空。文章來源:http://www.zghlxwxcb.cn/news/detail-684678.html
- 接口層增加校驗:用戶鑒權、參數(shù)校驗(請求參數(shù)是否合法、請求字段是否不存在等等);
- 緩存空值/缺省值:發(fā)生緩存穿透時,我們可以在Redis中緩存一個空值或者缺省值(例如,庫存缺省值為0),這樣就避免了把大量請求發(fā)送給數(shù)據庫處理,保持了數(shù)據庫的正常運行。這種方法會存在兩個問題:
a. 如果有大量的Key穿透,緩存空對象會占用寶貴的內存空間。針對這種情況可以給空對象設置過期時間。
b. 設置過期時間之后,可能會有緩存與數(shù)據庫不一致的情況。 - 布隆過濾器:快速判斷數(shù)據是否存在,避免從數(shù)據庫中查詢數(shù)據是否存在,減輕數(shù)據庫壓力
- 布隆過濾器實戰(zhàn)
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.15.0</version>
</dependency>
import org.redisson.Redisson;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.redisson.config.Config;
public class RedissonBloomFilter {
public static void main(String[] args) {
Config config = new Config();
config.useSingleServer().setAddress("redis://127.0.0.1:6379");
RedissonClient client = Redisson.create(config);
RBloomFilter<String> bloomFilter = client.getBloomFilter("test-bloom-filter");
// 初始化布隆過濾器,數(shù)組長度100W,誤判率 1%
bloomFilter.tryInit(1000000L, 0.01);
// 添加數(shù)據
bloomFilter.add("Shawn");
// 判斷是否存在
System.out.println(bloomFilter.contains("xujunson"));
System.out.println(bloomFilter.contains("Shawn"));
}
}
總結
文章來源地址http://www.zghlxwxcb.cn/news/detail-684678.html
到了這里,關于redis緩存雪崩、穿透、擊穿解決方案的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網!