婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > Redis使用元素刪除的布隆過濾器來解決緩存穿透問題

Redis使用元素刪除的布隆過濾器來解決緩存穿透問題

熱門標簽:企業智能外呼系統價格多少 沈陽營銷電銷機器人招商 高德地圖標注商戶位置 福州電銷機器人源代碼 徐州ai電銷機器人原理 南京400電話怎樣辦理 機器人外呼系統軟件存在問題 智能電銷機器人銷售話術 兗州電話外呼營銷系統

前言

在我們日常開發中,Redis使用場景最多的就是作為緩存和分布式鎖等功能來使用,而其用作緩存最大的目的就是為了降低數據庫訪問。但是假如我們某些數據并不存在于Redis當中,那么請求還是會直接到達數據庫,而一旦在同一時間大量緩存失效或者一個不存在緩存的請求被惡意訪問,這些都會導致數據庫壓力驟增,這就是本文要講述的緩存穿透,緩存擊穿和緩存雪崩的問題,而布隆過濾器正是緩存穿透的一種解決方案

緩存雪崩

緩存雪崩指的是Redis當中的大量緩存在同一時間全部失效,而假如恰巧這一段時間同時又有大量請求被發起,那么就會造成請求直接訪問到數據庫,可能會把數據庫沖垮。

緩存雪崩一般形容的是緩存中沒有而數據庫中有的數據,而因為時間到期導致請求直達數據庫。

解決方案

解決緩存雪崩的方法有很多:

1、加鎖,保證單線程訪問緩存。這樣就不會有很多請求同時訪問到數據庫。

2、失效時間不要設置成一樣。典型的就是初始化預熱數據的時候,將數據存入緩存時可以采用隨機時間來確保不會咋同一時間有大量緩存失效。

3、內存允許的情況下,可以將緩存設置為永不失效。

緩存擊穿

緩存擊穿和緩存雪崩很類似,區別就是緩存擊穿一般指的是單個緩存失效,而同一時間又有很大的并發請求需要訪問這個key,從而造成了數據庫的壓力。

解決方案

解決緩存擊穿的方法和解決緩存雪崩的方法很類似:

1、加鎖,保證單線程訪問緩存。這樣第一個請求到達數據庫后就會重新寫入緩存,后續的請求就可以直接讀取緩存。2、內存允許的情況下,可以將緩存設置為永不失效。

 緩存穿透

緩存穿透和上面兩種現象的本質區別就是這時候訪問的數據其在數據庫中也不存在,那么既然數據庫不存在,所以緩存里面肯定也不會存在,這樣如果并發過大就會造成數據源源不斷的到達數據庫,給數據庫造成極大壓力。

解決方案

對于緩存穿透問題,加鎖并不能起到很好地效果,因為本身key就是不存在,所以即使控制了線程的訪問數,但是請求還是會源源不斷的到達數據庫。

解決緩存穿透問題一般可以采用以下方案配合使用:

1、接口層進行校驗,發現非法的key直接返回。比如數據庫中采用的是自增id,那么如果來了一個非整型的id或者負數id可以直接返回,或者說如果采用的是32位uuid,那么發現id長度不等于32位也可以直接返回。

2、將不存在的數據也進行緩存,可以直接緩存一個空或者其他約定好的無效value。采用這種方案最好將key設置一個短期失效時間,否則大量不存在的key被存儲到Redis中,也會占用大量內存。

布隆過濾器(Bloom Filter)

針對上面緩存穿透的解決方案,我們思考一下:假如一個key可以繞過第1種方法的校驗,而此時有大量的不存在key被訪問(如1億個或者10億個),那么這時候全部存儲到緩存,會占用非常大的空間,會浪費大量服務器內存,導致內存不足。

那么有沒有一種更好的解決方案呢?這就是我們接下來要介紹的布隆過濾器,布隆過濾器就可以最大程度的解決key值過多的這個問題。

什么是布隆過濾器

可能大部分人都知道有這么一個面試問題:如何在10億的海量的無序的數據中快速判斷一個元素是否存在?

要解決這個問題就需要用到布隆過濾器,否則大部分服務器的內存是無法存儲這么大的數量級的數據的。

布隆過濾器(Bloom Filter)是由布隆在1970年提出的。它實際上是一個很長的二進制向量(位圖)和一系列隨機映射函數(哈希函數)。

布隆過濾器可以用于檢索一個元素是否在一個集合中。它的優點是空間效率和查詢時間都比一般的算法要好的多,缺點是有一定的誤識別率而且刪除困難。

位圖(Bitmap)

Redis當中有一種數據結構就是位圖,布隆過濾器其中重要的實現就是位圖的實現,也就是位數組,并且在這個數組中每一個位置只有0和1兩種狀態,每個位置只占用1個比特(bit),其中0表示沒有元素存在,1表示有元素存在。如下圖所示就是一個簡單的布隆過濾器示例(一個key值經過哈希運算和位運算就可以得出應該落在哪個位置):

哈希碰撞

上面我們發現,lonelywolf落在了同一個位置,這種不同的key值經過哈希運算后得到相同值的現象就稱之為哈希碰撞。發生哈希碰撞之后再經過位運算,那么最后肯定會落在同一個位置。

如果發生過多的哈希碰撞,就會影響到判斷的準確性,所以為了減少哈希碰撞,我們一般會綜合考慮以下2個因素:

1、增大位圖數組的大小(位圖數組越大,占用的內存越大)。

2、增加哈希函數的次數(同一個key值經過1個函數相等了,那么經過2個或者更多個哈希函數的計算,都得到相等結果的概率就自然會降低了)。

上面兩個方法我們需要綜合考慮:比如增大位數組,那么就需要消耗更多的空間,而經過越多的哈希計算也會消耗cpu影響到最終的計算時間,所以位數組到底多大,哈希函數次數又到底需要計算多少次合適需要具體情況具體分析。

布隆過濾器的2大特點

下面這個就是一個經過了2次哈希函數得到的布隆過濾器,根據下圖我們很容易看到,假如我們的Redis根本不存在,但是Redis經過2次哈希函數之后得到的兩個位置已經是1了(一個是wolf通過f2得到,一個是Nosql通過f1得到)。


所以通過上面的現象,我們從布隆過濾器的角度可以得出布隆過濾器主要有2大特點:

1、如果布隆過濾器判斷一個元素存在,那么這個元素可能存在

2、如果布隆過濾器判斷一個元素不存在,那么這個元素一定不存在

而從元素的角度也可以得出2大特點:

1、如果元素實際存在,那么布隆過濾器一定會判斷存在

2、如果元素不存在,那么布隆過濾器可能會判斷存在

PS:需要注意的是,如果經過N次哈希函數,則需要得到的N個位置都是1才能判定存在,只要有一個是0,就可以判定為元素不存在布隆過濾器中

fpp

因為布隆過濾器中總是會存在誤判率,因為哈希碰撞是不可能百分百避免的。布隆過濾器對這種誤判率稱之為假陽性概率,即:False Positive Probability,簡稱為fpp。

在實踐中使用布隆過濾器時可以自己定義一個fpp,然后就可以根據布隆過濾器的理論計算出需要多少個哈希函數和多大的位數組空間。需要注意的是這個fpp不能定義為100%,因為無法百分保證不發生哈希碰撞。

布隆過濾器的實現(Guava)

在Guava的包中提供了布隆過濾器的實現,下面就通過Guava來體會一下布隆過濾器的應用:
1、引入pom依賴

dependency>
   groupId>com.google.guava/groupId>
   artifactId>guava/artifactId>
   version>29.0-jre/version>
/dependency>

2、新建一個布隆過濾器的測試demo:

package com.lonelyWolf.redis;

import com.google.common.base.Charsets;
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;

import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

public class BloomFilterDemo {
    private static final int expectedInsertions = 1000000;

    public static void main(String[] args) {
        BloomFilterString> bloomFilter = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8),expectedInsertions);

        ListString> list = new ArrayList>(expectedInsertions);


        for (int i = 0; i  expectedInsertions; i++) {
            String uuid = UUID.randomUUID().toString();
            bloomFilter.put(uuid);
            list.add(uuid);
        }

        int rightNum1 = 0;
        int wrongNum1 = 0;

        NumberFormat percentFormat =NumberFormat.getPercentInstance();
        percentFormat.setMaximumFractionDigits(2); //最大小數位數

        for (int i=0;i  500;i++){
            String key = list.get(i);
            if (bloomFilter.mightContain(key)){
                if (list.contains(key)){
                    rightNum1++;
                }else {
                    wrongNum1++;
                }
            }
        }
        System.out.println("布隆過濾器認為存在的key值數:" + rightNum1);
        System.out.println("-----------------------分割線---------------------------------");

        int rightNum2 = 0;
        int wrongNum2 = 0;

        for (int i=0;i  5000;i++){
            String key = UUID.randomUUID().toString();
            if (bloomFilter.mightContain(key)){
                if (list.contains(key)){
                    rightNum2++;
                }else {
                    wrongNum2++;
                }
            }
        }

        System.out.println("布隆過濾器認為存在的key值數:" + rightNum2);
        System.out.println("布隆過濾器認為不存在的key值數:" + wrongNum2);
        System.out.println("布隆過濾器的誤判率為:" + percentFormat.format((float)wrongNum2 / 5000));
    }
}

運行之后,第一部分輸出的值一定是和for循環內的值相等,也就是百分百匹配,即滿足了原則1:如果元素實際存在,那么布隆過濾器一定會判斷存在
第二部分的輸出的誤判率即fpp總是在3%左右,而且隨著for循環的次數越大,越接近3%。即滿足了原則2:如果元素不存在,那么布隆過濾器可能會判斷存在

這個3%的誤判率是如何來的呢?我們進入創建布隆過濾器的create方法,發現默認的fpp就是0.03:


對于這個默認的3%的fpp需要多大的位數組空間和多少次哈希函數得到的呢?在BloomFilter類下面有兩個default方法可以獲取到位數組空間大小和哈希函數的個數:

  • optimalNumOfHashFunctions:獲取哈希函數的次數
  • optimalNumOfBits:獲取位數組大小

debug進去看一下:


得到的結果是7298440 bit=0.87M,然后經過了5次哈希運算。可以發現這個空間占用是非常小的,100W的key才占用了0.87M。

PS:點擊這里可以進入網站計算bit數組大小和哈希函數個數。

布隆過濾器的如何刪除

上面的布隆過濾器我們知道,判斷一個元素存在就是判斷對應位置是否為1來確定的,但是如果要刪除掉一個元素是不能直接把1改成0的,因為這個位置可能存在其他元素,所以如果要支持刪除,那我們應該怎么做呢?最簡單的做法就是加一個計數器,就是說位數組的每個位如果不存在就是0,存在幾個元素就存具體的數字,而不僅僅只是存1,那么這就有一個問題,本來存1就是一位就可以滿足了,但是如果要存具體的數字比如說2,那就需要2位了,所以帶有計數器的布隆過濾器會占用更大的空間

帶有計數器的布隆過濾器

下面就是一個帶有計數器的布隆過濾器示例
1、引入依賴:

dependency>
    groupId>com.baqend/groupId>
    artifactId>bloom-filter/artifactId>
    version>1.0.7/version>
/dependency>

2、新建一個帶有計數器的布隆過濾器demo:

package com.lonelyWolf.redis.bloom;

import orestes.bloomfilter.FilterBuilder;

public class CountingBloomFilter {
    public static void main(String[] args) {
        orestes.bloomfilter.CountingBloomFilterString> cbf = new FilterBuilder(10000,
                0.01).countingBits(8).buildCountingBloomFilter();

        cbf.add("zhangsan");
        cbf.add("lisi");
        cbf.add("wangwu");
        System.out.println("是否存在王五:" + cbf.contains("wangwu")); //true
        cbf.remove("wangwu");
        System.out.println("是否存在王五:" + cbf.contains("wangwu")); //false
    }
}

構建布隆過濾器前面2個參數一個就是期望的元素數,一個就是fpp值,后面的countingBits參數就是計數器占用的大小,這里傳了一個8位,即最多允許255次重復,如果不傳的話這里默認是16位大小,即允許65535次重復。

總結

本文主要講述了使用Redis存在的三種問題:緩存雪崩緩存擊穿緩存穿透。并分別對每種問題的解決方案進行了描述,最后著重介紹了緩存穿透的解決方案:布隆過濾器。原生的布隆過濾器不支持刪除,但是可以引入一個計數器實現帶有計數器的布隆過濾器來實現刪除功能,同時在最后也提到了,帶有計數器的布隆過濾器會占用更多的空間問題。

到此這篇關于Redis使用元素刪除的布隆過濾器來解決緩存穿透問題的文章就介紹到這了,更多相關Redis 緩存穿透內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • 詳解Redis緩存穿透/擊穿/雪崩原理及其解決方案
  • java若依框架集成redis緩存詳解
  • 關于redisson緩存序列化的幾枚大坑說明
  • springboot使用Redis作緩存使用入門教程
  • 淺談Redis 緩存的三大問題及其解決方案
  • 淺談java如何實現Redis的LRU緩存機制
  • 在項目中使用redis做緩存的一些思路

標簽:本溪 景德鎮 大理 邯鄲 吉安 昭通 鶴崗 丹東

巨人網絡通訊聲明:本文標題《Redis使用元素刪除的布隆過濾器來解決緩存穿透問題》,本文關鍵詞  Redis,使用,元素,刪除,的,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《Redis使用元素刪除的布隆過濾器來解決緩存穿透問題》相關的同類信息!
  • 本頁收集關于Redis使用元素刪除的布隆過濾器來解決緩存穿透問題的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    亚洲成人自拍网| 欧美一区二区在线播放| 91麻豆视频网站| 欧美成人一区二区| 午夜精品免费在线观看| 欧美在线免费观看视频| 亚洲日本一区二区三区| 91免费看片在线观看| 国产精品 日产精品 欧美精品| 久久伊人蜜桃av一区二区| 丁香另类激情小说| 国产日韩三级在线| 精品视频在线免费| 香蕉影视欧美成人| 欧美大尺度电影在线| 国产在线麻豆精品观看| 精品视频1区2区| 麻豆精品一区二区综合av| 日韩欧美一二三区| 成人在线视频首页| 中文字幕一区二区三中文字幕| 色老汉一区二区三区| 亚洲午夜电影在线| 日本一区二区三区视频视频| 色婷婷久久99综合精品jk白丝| 一二三区精品视频| 欧美va亚洲va香蕉在线| 91啪九色porn原创视频在线观看| 7777精品伊人久久久大香线蕉经典版下载 | 色婷婷综合久色| 亚洲精品水蜜桃| 26uuu亚洲综合色| 成人精品高清在线| 亚洲第一电影网| 久久日韩粉嫩一区二区三区| 不卡电影免费在线播放一区| 香蕉成人伊视频在线观看| 久久久久久夜精品精品免费| 欧美偷拍一区二区| 国产一区欧美日韩| 亚洲综合色自拍一区| 美女网站在线免费欧美精品| 亚洲青青青在线视频| 精品国产一区二区三区久久影院| av爱爱亚洲一区| 精品一区中文字幕| 亚洲综合激情另类小说区| 中文天堂在线一区| 日本韩国一区二区三区| 日韩二区三区四区| 亚洲欧美日本韩国| 国产精品视频yy9299一区| 欧美在线观看18| av网站一区二区三区| 国产盗摄精品一区二区三区在线| 亚洲午夜免费视频| 亚洲丝袜美腿综合| 欧美国产97人人爽人人喊| 欧美精品一区二区三区蜜桃| 777久久久精品| 欧美日韩不卡视频| 7777女厕盗摄久久久| 三级不卡在线观看| 日本中文字幕不卡| 亚洲最色的网站| 一区二区三区日韩欧美精品| 亚洲国产cao| 日韩国产精品大片| 精品一区免费av| 成人免费福利片| 免费在线观看不卡| 国内不卡的二区三区中文字幕| 久久99精品久久久久久动态图| 九九久久精品视频| 成人久久久精品乱码一区二区三区| 国产精品91一区二区| 欧美精品一区二区三区在线播放| 欧美精品一区二| 中文字幕一区二区三区不卡在线 | 中文字幕一区二区三区色视频| 国产精品色婷婷| 中文字幕一区二区三区在线播放 | 免费美女久久99| 国产在线一区二区综合免费视频| 成人精品亚洲人成在线| 欧美专区亚洲专区| 日韩欧美一二三| 国产精品久久二区二区| 91年精品国产| 亚洲在线成人精品| 国产在线一区二区综合免费视频| 99久久99久久精品免费看蜜桃| 欧美日韩高清不卡| 国产精品免费免费| 日韩成人一级片| 国产iv一区二区三区| 欧美日韩aaa| 国产精品视频yy9299一区| 亚洲成人av中文| 国产精品91一区二区| 91精品久久久久久久久99蜜臂| 日本一区二区视频在线| 天天影视涩香欲综合网| 久久综合色婷婷| 久久99国产精品免费网站| 91网站最新网址| 欧美mv和日韩mv的网站| 一区二区三区成人| 成人精品视频一区二区三区| 欧美一二三四区在线| 一区二区在线观看av| 粉嫩av一区二区三区在线播放| 91精品蜜臀在线一区尤物| 日韩欧美一级二级| 亚洲综合自拍偷拍| 成人黄色电影在线 | 91精品国产91久久久久久最新毛片| 97精品久久久久中文字幕| av午夜精品一区二区三区| 精品久久免费看| 有坂深雪av一区二区精品| 久久精品噜噜噜成人av农村| 成人黄色网址在线观看| 亚洲精品在线免费观看视频| 亚洲国产精品天堂| www.亚洲免费av| 国产精品一区二区免费不卡| av激情亚洲男人天堂| 欧美一区2区视频在线观看| 一级女性全黄久久生活片免费| 国产成人午夜电影网| 久久久不卡网国产精品一区| 福利一区二区在线| 国产日韩亚洲欧美综合| 国产成人免费在线观看| 欧美性大战久久久| 日韩毛片在线免费观看| 91视频国产资源| 亚洲精品福利视频网站| 欧美自拍偷拍一区| 图片区日韩欧美亚洲| 3751色影院一区二区三区| 日韩影院免费视频| 欧美va在线播放| 粉嫩在线一区二区三区视频| 国产精品国产自产拍高清av王其| 国产99久久久国产精品免费看| 精品99999| 国产91丝袜在线播放0| 亚洲欧洲成人自拍| 日本乱人伦一区| 日韩欧美亚洲国产精品字幕久久久| 日韩av中文字幕一区二区| 日韩一区二区三区四区五区六区 | 天天亚洲美女在线视频| 欧美日韩高清一区二区三区| 另类小说综合欧美亚洲| 久久久一区二区三区捆绑**| 视频一区在线视频| 日韩精品一区国产麻豆| 国产激情一区二区三区桃花岛亚洲| 国产精品美日韩| 欧美三区在线视频| 国产在线播精品第三| 自拍偷拍欧美激情| 国产精品美女久久久久aⅴ| 欧美一区二区三区免费视频 | 青青草伊人久久| 久久理论电影网| 在线观看成人小视频| 九一九一国产精品| 91传媒视频在线播放| 轻轻草成人在线| 国产精品美日韩| 欧美电影免费观看完整版| aa级大片欧美| 激情偷乱视频一区二区三区| 亚洲免费av网站| 久久久国际精品| 欧美一区二区三区男人的天堂| 成人免费视频一区二区| 国产欧美一二三区| 欧美日韩视频在线第一区| 成人国产亚洲欧美成人综合网| 日韩福利电影在线观看| 综合久久久久久久| 国产午夜精品久久| 日韩免费视频一区二区| 欧美精选在线播放| 欧美视频在线一区| 在线看不卡av| 色综合欧美在线视频区| 成人深夜视频在线观看| 久久 天天综合| 久色婷婷小香蕉久久| 亚洲成人av中文| 亚洲国产精品人人做人人爽| 亚洲激情图片qvod| 亚洲欧美另类在线| 成人v精品蜜桃久久一区|