redis中使用bloomfilter的白名單功能解決緩存穿透問(wèn)題
一 緩存預(yù)熱
1.1 緩存預(yù)熱
將需要的數(shù)據(jù)提前緩存到緩存redis中,可以在服務(wù)啟動(dòng)時(shí)候,或者在使用前一天完成數(shù)據(jù)的同步等操作。保證后續(xù)能夠正常使用。
1.2 緩存穿透
在redis中,查詢r(jià)edis緩存數(shù)據(jù)沒(méi)有內(nèi)容,接著查詢mysql數(shù)據(jù)庫(kù),也沒(méi)有需要的內(nèi)容,做了兩次無(wú)用的查詢。進(jìn)而造成mysql數(shù)據(jù)庫(kù)的負(fù)擔(dān),造成一系列的風(fēng)險(xiǎn)。
解決辦法:bloomfilter+白名單實(shí)現(xiàn)過(guò)濾。
1.3 白名單的作用
白名單里面有才讓允許通過(guò),沒(méi)有的內(nèi)容則不允許通過(guò)。但是存在誤判的情況,比如bloomfilter中存在查詢的內(nèi)容且允許通過(guò),但是并不是我們真正需要的那個(gè)內(nèi)容。
1.4 白名單入門案例
public class WhiteList { public static void main(String[] args) { testGuavaWithBloomFilter(); } public static void testGuavaWithBloomFilter() { //1 創(chuàng)建guava版布隆過(guò)濾器 BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), 100); //2 判斷指定的元素是否存在 System.out.println(bloomFilter.mightContain(1)); System.out.println(bloomFilter.mightContain(2)); System.out.println(); //3 講元素新增進(jìn)入bloomfilter bloomFilter.put(1); bloomFilter.put(2); System.out.println(bloomFilter.mightContain(1)); System.out.println(bloomFilter.mightContain(2)); } }
結(jié)果:
1.5 白名單+過(guò)濾器的實(shí)現(xiàn)案例
邏輯: guava布隆過(guò)濾器插入100萬(wàn)樣本數(shù)據(jù)并額外10W測(cè)試是否存在,這10w的數(shù)據(jù)在100w的數(shù)據(jù)可能存在相同的情況,存儲(chǔ)到相同位置。比如規(guī)則為m%3,則 1,4,7放到同一個(gè)位置槽中。
1.5.1 代碼邏輯
1.controller
@RestController @Slf4j public class GuvaFilter { @Resource private GuavaBloomFilterService guavaBloomFilterService; @ApiOperation("guava布隆過(guò)濾器插入100萬(wàn)樣本數(shù)據(jù)并額外10W測(cè)試是否存在") @RequestMapping(value = "/guavafilter",method = RequestMethod.GET) public void guavaBloomFilter() { guavaBloomFilterService.guavaBloomFilter(); } }
2.service
@Service @Slf4j public class GuavaBloomFilterService { //1 定義一個(gè)常量 public static final int _1W = 10000; //2 定義我們guava布隆過(guò)濾器,初始容量 public static final int SIZE = 100 * _1W; //3 誤判率,它越小誤判的個(gè)數(shù)也就越少(思考,是否可以是無(wú)限小??沒(méi)有誤判豈不是更好) public static double fpp = 0.01;//0.01 0.000000000000001 //4 創(chuàng)建guava布隆過(guò)濾器 private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(), SIZE,fpp); public void guavaBloomFilter() { //1 先讓bloomFilter加入100W白名單數(shù)據(jù) for (int i = 1; i <= SIZE ; i++) { bloomFilter.put(i); } //2 故意取10W個(gè)不在合法范圍內(nèi)的數(shù)據(jù),來(lái)進(jìn)行誤判率的演示 ArrayList<Integer> list = new ArrayList<>(10 * _1W); //3 驗(yàn)證 for (int i = SIZE+1; i <= SIZE+(10 * _1W) ; i++) { if(bloomFilter.mightContain(i)) { log.info("被誤判了:{}",i); list.add(i); } } log.info("誤判總數(shù)量:{}",list.size()); } }
3.截圖
控制臺(tái)打印日志:
1.6 bloomfilter總結(jié)
bloomfilter作用:查詢的內(nèi)容A,一定不存在,在過(guò)濾器中查詢肯定沒(méi)有;如果存在,但是存在誤判的情況,但是誤判率很小,可以忽略。
1.7 黑名單的使用
黑名單:在黑名單的存在的內(nèi)容,就不再推薦;不存在則推薦。
應(yīng)用案例: 抖音等媒體的推薦內(nèi)容。
到此這篇關(guān)于redis中使用bloomfilter的白名單功能解決緩存穿透問(wèn)題的文章就介紹到這了,更多相關(guān)redis bloomfilter解決緩存穿透內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Redis報(bào)錯(cuò):Could not create server TCP 
這篇文章主要介紹了Redis報(bào)錯(cuò):Could not create server TCP listening socket 127.0.0.1:6379: bind:解決方法,是安裝與啟動(dòng)Redis過(guò)程中比較常見的問(wèn)題,需要的朋友可以參考下2023-06-06redis集合類型_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
這篇文章給大家介紹了redis集合類型的常用方法,感興趣的朋友參考下吧2017-08-08Linux下安裝Redis 6.0.5的實(shí)現(xiàn)
本文詳細(xì)介紹了在Linux系統(tǒng)下安裝Redis 6.0.5的步驟,包括安裝準(zhǔn)備、編譯安裝、啟動(dòng)服務(wù)、設(shè)置密碼和配置文件修改等,具有一定的參考價(jià)值,感興趣的可以了解一下2025-02-02關(guān)于使用IDEA的springboot框架往Redis里寫入數(shù)據(jù)亂碼問(wèn)題
這篇文章主要介紹了用IDEA的springboot框架往Redis里寫入數(shù)據(jù)亂碼問(wèn)題,本文給大家分享解決方法通過(guò)圖文示例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10