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

Redis使用布隆過濾器解決緩存雪崩的問題

 更新時間:2024年02月05日 09:29:53   作者:武梓龍_Wzill  
布隆過濾器可以幫助我們解決Redis緩存雪崩的問題,那什么是布隆過濾器、布隆過濾器又是如何使用如何解決緩存雪崩的問題的,讓我們帶著這一系列的問題去詳細了解布隆過濾器,感興趣的小伙伴跟著小編一起來看看吧

背景介紹

布隆過濾器可以幫助我們解決Redis緩存雪崩的問題,那什么是布隆過濾器、布隆過濾器又是如何使用如何解決緩存雪崩的問題的,讓我們帶著這一系列的問題去詳細了解布隆過濾器。

概念說明

布隆過濾器是一種用于快速判斷一個元素是否屬于一個集合的數(shù)據(jù)結(jié)構(gòu)。它通常用于大規(guī)模數(shù)據(jù)集合中,可以快速判斷一個元素是否可能存在于集合中,但不能確定一定存在。布隆過濾器的主要優(yōu)點是占用內(nèi)存少、查詢速度快,并且可以容忍一定的誤判率。

原理說明

布隆過濾器由一個位數(shù)組和多個哈希函數(shù)組成。位數(shù)組通常初始化為0,哈希函數(shù)用于將元素映射到位數(shù)組中的多個位置。當一個元素被加入到布隆過濾器中時,它會被哈希函數(shù)映射到位數(shù)組的多個位置,然后將這些位置的值設(shè)為1。當查詢一個元素是否存在于布隆過濾器中時,哈希函數(shù)會將元素映射到位數(shù)組的多個位置,然后檢查這些位置的值是否都為1,如果有一個位置的值為0,則可以確定元素一定不存在于集合中,如果所有位置的值都為1,則元素可能存在于集合中。

布隆過濾器的誤判率取決于位數(shù)組的大小和哈希函數(shù)的數(shù)量。通常情況下,誤判率隨著位數(shù)組大小的增加而減小,但會占用更多的內(nèi)存。因此,使用布隆過濾器時需要根據(jù)實際情況權(quán)衡誤判率和內(nèi)存占用。

在這里插入圖片描述

解決穿透

我們還可以在存儲和緩存之前,加?個布隆過濾器,做?層過濾。布隆過濾器?會保存數(shù)據(jù)是否存在,如果判斷數(shù)據(jù)不存在,就不會訪問存儲。

在這里插入圖片描述

安裝使用

安裝過程

Redis為普通安裝的配置方式

1、下載布隆過濾器這個插件

wget https://github.com/RedisLabsModules/rebloom/archive/v2.2.6.tar.gz

2、解壓文件

tar -zxvf v2.2.6.tar.gz

在這里插入圖片描述

3、編輯插件

# 到RedisBloom對應(yīng)目錄
cd /usr/local/redis/RedisBloom-2.2.6
# 編譯插件
make

4、Redis集成RedisBloom插件

# vim查看redis.conf
vim /usr/local/redis/config/redis.conf
# 在文件后面添加如下配置
loadmodule /usr/local/redis/RedisBloom-2.2.6/redisbloom.so

在這里插入圖片描述

5、配置完之后重啟Redis即可。

Redis為Docker鏡像安裝的配置方式

1、創(chuàng)建文件夾以及配置文件,用于掛在redis啟動的后容器中的文件,方便我們在容器外部操作redis的配置

mkdir data  ##創(chuàng)建文件夾
touch redis.conf  ## 創(chuàng)建文件

2、在我們創(chuàng)建的redis.conf文件中添加一行配置loadmodule /data/RedisBloom-2.2.6/redisbloom.so

在這里插入圖片描述

3、隨后直接使用dokcer run命令進行啟動

docker run -p 6379:6379 --name redis -v /root/redis/data:/data -v 
/root/redis/redis.conf:/etc/redis/redis.conf --restart=always 
--network host  -d redis:5.0.7 redis-server /etc/redis/redis.conf

這個命令是用于在 Docker 中運行 Redis 容器,并進行一些配置。下面是對每個參數(shù)的解釋:

  • -p 6379:6379: 將 Docker 容器的端口 6379 映射到主機的端口 6379,以便可以從主機訪問 Redis 服務(wù)。
  • –name redis: 指定容器的名稱為 “redis”。
  • -v /root/redis/data:/data: 將主機的 /root/redis/data 目錄掛載到容器的 /data 目錄,用于持久化保存 Redis 數(shù)據(jù)。
  • -v /root/redis/redis.conf:/etc/redis/redis.conf: 將主機的 /root/redis/redis.conf 配置文件掛載到容器的 /etc/redis/redis.conf,使用該配置文件作為 Redis 的配置。
  • –restart=always: 設(shè)置容器在退出時自動重新啟動。
  • –network host: 使用主機網(wǎng)絡(luò)模式,容器將共享主機的網(wǎng)絡(luò)棧。
  • -d: 在后臺運行容器。
  • redis:5.0.7: 指定使用的 Redis 鏡像及其版本號。
  • redis-server /etc/redis/redis.conf: 在容器中執(zhí)行的命令,即啟動 Redis 服務(wù)器,并使用指定的配置文件。

執(zhí)行上述操作redis容器如果啟動沒有問題那么我們的布隆過濾器的插件和redis都安裝并啟動成功了,如果沒有啟動成功可以通過docker logs 查看一下redis的啟動過程中出現(xiàn)什么問題。

具體使用

控制臺操作命令說明

  • BF.ADD:向布隆過濾器中添加一個元素。
BF.ADD <key> <item>
  • BF.EXISTS:檢查一個元素是否存在于布隆過濾器中。
BF.EXISTS <key> <item>
  • -BF.MADD:向布隆過濾器中批量添加多個元素。
BF.MADD <key> <item> [item ...]
  • BF.MEXISTS:批量檢查多個元素是否存在于布隆過濾器中。
BF.MEXISTS <key> <item> [item ...]
  • BF.INFO:獲取布隆過濾器的信息,包括容量、誤判率等。
BF.INFO <key>
  • BF.RESERVE:創(chuàng)建一個新的布隆過濾器,并指定容量和誤判率。
BF.RESERVE <key> <error_rate> <capacity>
  • BF.COUNT:統(tǒng)計布隆過濾器中已添加的元素數(shù)量。
BF.COUNT <key>

給user過濾器添加一個元素,如果我們沒有添加創(chuàng)建布隆過濾器,系統(tǒng)會給我們創(chuàng)建一個,其中布隆過濾器的容量為100,判錯率為0.01這是布隆過濾器的默認配置,我們可以在創(chuàng)建布隆過濾器的時候進行修改。

在這里插入圖片描述

Spring Boot集成布隆過濾器

1、引入依賴:這里使用的redis的過濾器所以用到的依賴直接使用的spring-data-redis這個就可以了。

        <!--redis的依賴-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2、布隆過濾器的工具類

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.core.script.RedisScript;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class RedisBloomUtil {
    @Autowired
    private RedisTemplate redisTemplate;
    // 初始化一個布隆過濾器
    public Boolean tryInitBloomFilter(String key, long expectedInsertions, double falseProbability) {
        Boolean keyExist = redisTemplate.hasKey(key);
        if(keyExist) {
            return false;
        }
        RedisScript<Boolean> script = new DefaultRedisScript<>(bloomInitLua(), Boolean.class);
        RedisSerializer stringSerializer = redisTemplate.getStringSerializer();
        redisTemplate.execute(script, stringSerializer, stringSerializer, Collections.singletonList(key), falseProbability+"", expectedInsertions+"");
        return true;
    }
    // 添加元素
    public Boolean addInBloomFilter(String key, Object arg) {
        RedisScript<Boolean> script = new DefaultRedisScript<>(addInBloomLua(), Boolean.class);
        return (Boolean) redisTemplate.execute(script, Collections.singletonList(key), arg);
    }
    @Transactional
    // 批量添加元素
    public Boolean batchAddInBloomFilter(String key, Object... args) {
        RedisScript<Boolean> script = new DefaultRedisScript<>(batchAddInBloomLua(), Boolean.class);
        return (Boolean) redisTemplate.execute(script, Collections.singletonList(key), args);
    }
    // 查看某個元素是否是存在
    public Boolean existInBloomFilter(String key, Object arg) {
        RedisScript<Boolean> script = new DefaultRedisScript<>(existInBloomLua(), Boolean.class);
        return (Boolean) redisTemplate.execute(script, Collections.singletonList(key), arg);
    }
    // 批量查看元素是否存在
    public List batchExistInBloomFilter(String key, Object... args) {
        RedisScript<List> script = new DefaultRedisScript(batchExistInBloomLua(), List.class);
        List<Long> results = (List) redisTemplate.execute(script, Collections.singletonList(key), args);
        List<Boolean> booleanList = results.stream().map(res -> res == 1 ? true : false).collect(Collectors.toList());
        return booleanList;
    }


    private String bloomInitLua() {
        return "redis.call('bf.reserve', KEYS[1], ARGV[1], ARGV[2])";
    }
    private String addInBloomLua() {
        return "return redis.call('bf.add', KEYS[1], ARGV[1])";
    }
    private String batchAddInBloomLua() {
        StringBuilder sb = new StringBuilder();
        sb.append("for index, arg in pairs(ARGV)").append("\r\n");
        sb.append("do").append("\r\n");
        sb.append("redis.call('bf.add', KEYS[1], arg)").append("\r\n");
        sb.append("end").append("\r\n");
        sb.append("return true");
        return sb.toString();
    }
    private String existInBloomLua() {
        return "return redis.call('bf.exists', KEYS[1], ARGV[1])";
    }
    private String batchExistInBloomLua() {
        StringBuilder sb = new StringBuilder();
        sb.append("local results = {}").append("\r\n");
        sb.append("for index, arg in pairs(ARGV)").append("\r\n");
        sb.append("do").append("\r\n");
        sb.append("local exist = redis.call('bf.exists', KEYS[1], arg)").append("\r\n");
        sb.append("table.insert(results, exist)").append("\r\n");
        sb.append("end").append("\r\n");
        sb.append("return results;");
        return sb.toString();
    }
}

總結(jié)提升

布隆過濾器適用于需要快速判斷一個元素是否可能存在于集合中的場景,例如網(wǎng)絡(luò)爬蟲中的去重、緩存中的數(shù)據(jù)判斷等。但需要注意的是,布隆過濾器無法刪除元素,也無法準確地判斷一個元素是否存在于集合中,因此在一些場景下可能會產(chǎn)生誤判。

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

相關(guān)文章

  • Redis下載部署并加入idea應(yīng)用的小結(jié)

    Redis下載部署并加入idea應(yīng)用的小結(jié)

    這篇文章主要介紹了Redis下載部署并加入idea應(yīng)用,需要的朋友可以參考下
    2022-10-10
  • Redis創(chuàng)建并修改Lua 環(huán)境的實現(xiàn)方法

    Redis創(chuàng)建并修改Lua 環(huán)境的實現(xiàn)方法

    為了在Redis服務(wù)器中執(zhí)行Lua腳本, Redis在服務(wù)器內(nèi)嵌了一個Lua環(huán)境, 并對這個Lua環(huán)境進行了一系列修改,本文主要介紹了Redis創(chuàng)建并修改Lua 環(huán)境的實現(xiàn)方法,具有一定的參考價值,感興趣的可以了解一下
    2024-05-05
  • Redis操作相關(guān)命令之查看、停止、啟動命令

    Redis操作相關(guān)命令之查看、停止、啟動命令

    這篇文章主要介紹了Redis操作相關(guān)命令之查看、停止、啟動命令,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Redis列表類型的常用命令小結(jié)

    Redis列表類型的常用命令小結(jié)

    這篇文章給大家整理了在操作Redis列表類型中的常用命令,文章總結(jié)的很全面,對大家學習Redis具有一定的參考借鑒價值,下面來一起看看吧。
    2016-09-09
  • Redis Stream類型的使用詳解

    Redis Stream類型的使用詳解

    本文主要介紹了Redis Stream類型的使用詳解,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Redis的復(fù)制延遲優(yōu)化的實現(xiàn)步驟

    Redis的復(fù)制延遲優(yōu)化的實現(xiàn)步驟

    本文探討了Redis主從復(fù)制架構(gòu)中的復(fù)制延遲問題及其優(yōu)化策略,復(fù)制延遲主要由網(wǎng)絡(luò)延遲、節(jié)點性能不足和數(shù)據(jù)量過大等因素導(dǎo)致,下面就來介紹一下優(yōu)化方案,感興趣的可以了解一下
    2025-10-10
  • 詳解Redis實現(xiàn)分布式鎖的原理

    詳解Redis實現(xiàn)分布式鎖的原理

    分布式鎖,即分布式系統(tǒng)中的鎖,在單體應(yīng)用中我們通過鎖解決的是控制共享資源訪問的問題,而分布式鎖,就是解決了分布式系統(tǒng)中控制共享資源訪問的問題,本文講給大家詳細介紹一下Redis實現(xiàn)分布式鎖的原理,需要的朋友可以參考下
    2023-09-09
  • Redis高級用法以及golang代碼示例

    Redis高級用法以及golang代碼示例

    Redis是一個遠程內(nèi)存數(shù)據(jù)庫,它不僅性能強勁,而且還具有復(fù)制特性以及為解決問題而生的獨一無二的數(shù)據(jù)模型,這篇文章主要介紹了Redis高級用法以及golang代碼示例的相關(guān)資料,需要的朋友可以參考下
    2026-01-01
  • Redis緩存雪崩、緩存擊穿、緩存穿透詳解

    Redis緩存雪崩、緩存擊穿、緩存穿透詳解

    本文介紹了緩存雪崩、擊穿、穿透三種問題:雪崩因大量緩存同時失效導(dǎo)致數(shù)據(jù)庫壓力激增,需差異化TTL、多級緩存及熔斷機制;擊穿由熱點key失效引發(fā),可用互斥鎖、邏輯過期或預(yù)加載;穿透則因非法查詢穿透緩存,需布隆過濾器、空對象或參數(shù)校驗
    2025-07-07
  • Django使用Redis進行緩存詳細步驟

    Django使用Redis進行緩存詳細步驟

    這篇文章主要介紹了Django使用Redis進行緩存詳細流程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-08-08

最新評論

建平县| 新安县| 许昌市| 谢通门县| 灵山县| 葵青区| 松阳县| 盈江县| 体育| 新宾| 延庆县| 伊金霍洛旗| 金堂县| 陇川县| 萨迦县| 峨眉山市| 临朐县| 依安县| 五河县| 民县| 全南县| 远安县| 缙云县| 上犹县| 章丘市| 南漳县| 保德县| 乌恰县| 洪湖市| 新巴尔虎左旗| 庐江县| 营口市| 聂拉木县| 监利县| 星座| 栾川县| 车险| 桂林市| 化隆| 聊城市| 凌海市|