最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot使用布隆過濾器解決緩存穿透問題

 更新時間:2023年10月10日 08:38:09   作者:YIRC99  
緩存穿透是指當(dāng)緩存系統(tǒng)中無法命中需要的數(shù)據(jù)時,會直接請求底層存儲系統(tǒng)(如數(shù)據(jù)庫),但是如果請求的數(shù)據(jù)根本不存在,那么大量的請求就會直接穿透緩存層,本文將給大家介紹一下SpringBoot使用布隆過濾器解決緩存穿透問題,需要的朋友可以參考下

緩存穿透基礎(chǔ)介紹

緩存穿透是指當(dāng)緩存系統(tǒng)中無法命中需要的數(shù)據(jù)時,會直接請求底層存儲系統(tǒng)(如數(shù)據(jù)庫),但是如果請求的數(shù)據(jù)根本不存在,那么大量的請求就會直接穿透緩存層,直接訪問底層存儲系統(tǒng),導(dǎo)致底層系統(tǒng)壓力過大,甚至崩潰。這也是緩存系統(tǒng)面臨的一種常見攻擊。

說白了就是查詢大量不傳在的key  繞過緩存 直接查詢數(shù)據(jù)庫 導(dǎo)致緩存跟不不存在一樣 這就是緩存穿透

場景介紹

下面說下我的場景 我需要添加一個user 然后我再通過id去查詢  如果查詢有結(jié)果那就放入緩存 如果沒有那就直接查詢數(shù)據(jù)庫 ?

這是添加user的方法

這是查詢user的方法

問題描述

在這兩個方法中 我雖然加入的緩存的機制 但是在查詢user的方法中 會有一個問題 就是如果我查詢的id是不存在的 那就會一直查詢數(shù)據(jù)庫

@Cacheable(value = "userCache", key = "#id", condition = "#result != null")

當(dāng)然你可以說 我去掉注解上面的condition = "#result != null"   (這句話意思是condition 條件為真才緩存)  這樣就算我查詢一個不存在的id 然后將一個null或者空對象返回 然后再加入緩存不就可以啦  下次再去查詢這個不存在的id的時候 就不會走數(shù)據(jù)庫了  

可是 如果我每一次查詢的都是不同的并且不存在的id呢? 那么這個問題還是無法解決 那么接下來就可以引入布隆過濾器  布隆過濾器具體的原理我這里就不做解釋了

解決問題

第一步在maven中導(dǎo)入布隆過濾器  事先說明 導(dǎo)入的方法很多 我的方法不一定是最優(yōu)的 但是一定是能行的

在pom.xml中引入依賴

        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>30.1-jre</version>
        </dependency>
        Guava庫(Google Guava)是一個Google開發(fā)的Java工具庫,
        它提供了許多常用的Java工具類和數(shù)據(jù)結(jié)構(gòu),包括布隆過濾器(Bloom Filter)

創(chuàng)建項目結(jié)構(gòu) 這個不需要解釋吧 能看這種文章的 我相信項目結(jié)構(gòu)應(yīng)該都是能看懂的?

AppConfig的代碼如下 就是簡單的注入Bean對象

@Configuration
public class AppConfig {
    @Bean
    public BloomFilterService bloomFilterService() {
        return new BloomFilterService();
    }
}

BloomFilterService的代碼如下

public class BloomFilterService {
    private BloomFilter<Long> bloomFilter;
    public BloomFilterService(){
        // 創(chuàng)建一個布隆過濾器,設(shè)置期望插入的元素數(shù)量和誤判率
        int  bloomFilterSize = 1000;  // 期望插入的元素數(shù)量
        double falsePositiveRate = 0.001; // 誤判率
        bloomFilter = BloomFilter.create(Funnels.longFunnel(), bloomFilterSize, falsePositiveRate);
    }
    // 添加元素到布隆過濾器
    public void add(Long id){
        bloomFilter.put(id);
    }
    //判斷元數(shù)是否在布隆過濾器中
    public boolean contains(Long id){
        return bloomFilter.mightContain(id);
    }
}

接下來就是在controller中引入并且使用布隆過濾器了

正常注入

    @Autowired
    private BloomFilterService bloomFilterService;

然后在每一次添加對象之后都將用戶的id添加到布隆過濾器中

    @CachePut(value = "userCache", key = "#user.id") // value 指定緩存的名字
    @PostMapping
    public User save(User user){
        userService.save(user);
        bloomFilterService.add(user.getId()); 
        //這里注意必須要放在添加之后 因為一開始傳過來的user是沒有id的 會有空指針錯誤
        //這里利用的查詢回顯 不懂的可以去查查
        return user;
    }

然后更改查詢方法 這樣每一次查詢user的時候都會先過一遍布隆過濾器 然后再去查詢用戶 如果存在那么就加入緩存 不傳在就會被布隆過濾器攔截 注意去掉, condition = "#result != null" 這個好像跟 布隆有沖突 如果有懂的可以在評論區(qū)提一下

    @Cacheable(value = "userCache", key = "#id")
    @GetMapping("/{id}")
    public User getById(@PathVariable Long id){
        if (!bloomFilterService.contains(id)) {
            // ID 不合法,可以返回錯誤響應(yīng)或進(jìn)行其他處理
            return null;
        }
        User byId = userService.getById(id);
        return byId;
    }

最后的效果

在添加的時候會將id添加到布隆中 下一次查詢的時候如果添加的數(shù)據(jù)不合法 那就直接攔截

如果添加的數(shù)據(jù)是合法的 那么就會直接查緩存  如果緩存沒有那就直接查數(shù)據(jù)庫 然后再加入緩存

上面的效果我自己測試了發(fā)現(xiàn)是沒有什么問題的 本人的水平也不高 如果有發(fā)現(xiàn)什么問題歡迎評論區(qū)討論 謝謝觀看

以上就是SpringBoot使用布隆過濾器解決緩存穿透問題的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot緩存穿透的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論

扬州市| 左贡县| 七台河市| 乳源| 靖州| 华池县| 永新县| 綦江县| 江川县| 黄大仙区| 太和县| 宜丰县| 建始县| 石门县| 安阳市| 凌海市| 阿克陶县| 军事| 疏勒县| 雷山县| 马龙县| 信阳市| 伊金霍洛旗| 和政县| 合江县| 祁门县| 循化| 乌兰县| 宾阳县| 邵武市| 沁水县| 都匀市| 邢台市| 荆门市| 玛沁县| 敦化市| 嘉义县| 响水县| 惠东县| 景洪市| 克东县|