緩存穿透 - 布隆過濾器

一:緩存擊穿問題

 

緩存擊穿表示惡意用戶模擬請求很多緩存中不存在的數據,由於緩存中都沒有,導致這些請求短時間內直接落在了數據庫上,導致數據庫異常。這個我們在實際項目就遇到了,有些搶購活動、秒殺活動的接口API被大量的惡意用戶刷,導致短時間內數據庫c超時了,好在數據庫是讀寫分離,同時也有進行接口限流,hold住了。

解決方案的話:
方案1、使用互斥鎖排隊

方案2、接口限流與熔斷、降級

方案3、布隆過濾器

 

布隆過濾器是一種數據結構,比較巧妙的概率型數據結構(probabilistic data structure),特點是高效地插入和查詢,可以用來告訴你 “某樣東西一定不存在或者可能存在”

相比於傳統的 List、Set、Map 等數據結構,它更高效、佔用空間更少,但是缺點是其返回的結果是概率性的,而不是確切的

其次增加很麻煩,刪除實現不了

 

引包:

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
        </dependency>
BloomFilter bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8),10);// 存放元素個數10個
BloomFilter bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8),10,0.0002);//誤判率
bloomFilter.put(obj);

 

 

(三)緩存雪崩問題
緩存在同一時間內大量鍵過期(失效),接着來的一大波請求瞬間都落在了數據庫中導致連接異常。

解決方案:

方案1、也是像解決緩存穿透一樣加鎖排隊,實現同上;

方案2、建立備份緩存,緩存A和緩存B,A設置超時時間,B不設值超時時間,先從A讀緩存,A沒有讀B,並且更新A緩存和B緩存;

方案3、設置緩存超時時間的時候加上一個隨機的時間長度,比如這個緩存key的超時時間是固定的5分鐘加上隨機的2分鐘,醬紫可從一定程度上避免雪崩問題;
 

(四)緩存併發問題
這裏的併發指的是多個redis的client同時set key引起的併發問題。其實redis自身就是單線程操作,多個client併發操作,按照先到先執行的原則,先到的先執行,其餘的阻塞。當然,另外的解決方案是把redis.set操作放在隊列中使其串行化,必須的一個一個執行,具體的代碼就不上了,當然加鎖也是可以的,至於爲什麼不用redis中的事務,留給各位看官自己思考探究。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章