redis布隆过滤器RedisBloomFilter

基于Redis的布隆过滤器的实现 项目简介包含一个基于Redis的布隆过滤器的实现,以及应用到Scrapy中的Demo。地址:BloomFilterRedis布隆过滤器网上有很多介绍,推荐《数学之美》,介绍的很详尽,此处不再赘述。哈希函数布隆过滤器中需要n个哈希函数,我使用的是Arash Partow提供的常见哈希函数。建立在Redis上的布隆过滤器Redis中有一个数据结构叫做Bitmap(下方有官网详解),它提供一个最大长度为5 阅读详情
package org.olylakers.bloomfilter;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.pool.impl.GenericObjectPool.Config;

import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;

/**
 * BloomFilter based on redis
 * @author olylakers
 *
 * 2013-12-4 上午9:46:37 
 */
public class BloomFilter {
    
    private String hosts;
    private int timeout;
    private int maxKey;
    private float errorRate;
    private int hashFunctionCount;
    
    private int bitSize;
    
    private ShardedJedisPool pool;
    
    private String defaultKey = "redis:bloomfilter";
    private static final String hostConfig = "127.0.0.1:6001";
    
    public BloomFilter(String hosts, int timeout, float errorRate, int maxKey){
        this.hosts = hosts;
        this.timeout = timeout;
        this.maxKey = maxKey;
        this.errorRate = errorRate;
        String[] hostInfos = hosts.split(";");
        List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
        if(StringUtils.isNotBlank(hosts)){
            for (String hostInfo : hostInfos) {
                String[] host = hostInfo.split(":");
                if(host.length != 2){
                    throw new IllegalArgumentException("hosts should not be null or empty");
                }
                int port = 0;
                if(NumberUtils.isNumber(host[1])){
                    port = NumberUtils.toInt(host[1]);
                }
                shards.add(new JedisShardInfo(host[0],port,timeout));
            }  
        }else{
            throw new IllegalArgumentException("redis host.length != 2");
        }
        
        pool = initRedisPool(shards);
        
        bitSize = calcOptimalM(maxKey, errorRate);
        hashFunctionCount =calcOptimalK(bitSize, maxKey);
    }
    
    private ShardedJedisPool initRedisPool(List<JedisShardInfo> shards){
        Config config = new Config();
        //在借出的时候不测试有效性
        config.testOnBorrow = false;
        //在还回的时候不测试有效性
        config.testOnReturn = false;
        //最小空闲数
        config.minIdle = 8;
        //最大空闲数
        config.maxIdle = 50;
        //最大连接数
        config.maxActive = 50;
        //允许最大等待时间,2s,单位:ms
        config.maxWait = 2 * 1000;
        
        config.minEvictableIdleTimeMillis = 1000L * 60L * 60L * 5L;
        return new ShardedJedisPool(config,shards);
    }
    
    /**
     * add one object, using default key
     * @param bizId
     */
    public void add(int bizId){
        add(defaultKey, bizId);
    }
    
    /**
     * add one object using the specified key
     * @param key
     * @param bizId
     */
    public void add(String key, long bizId){
        int[] offset = HashUtils.murmurHashOffset(bizId, hashFunctionCount, bitSize);
        ShardedJedis jedis = null;
        boolean connected = true;
        try {
            jedis = pool.getResource();
            for (int i : offset) {
                jedis.setbit(key, i, true);
            }
        }finally{
            if(jedis != null){
                if(connected){
                    pool.returnResource(jedis);
                }else{
                    pool.returnBrokenResource(jedis);
                }
            }
        }
    }
    
    /**
     * add one object using the specified key
     * @param key
     * @param bizId
     */
    public void addWithPipe(String key, long bizId){
        int[] offset = HashUtils.murmurHashOffset(bizId, hashFunctionCount, bitSize);
        ShardedJedis jedis = null;
        boolean connected = true;
        try {
            jedis = pool.getResource();
            ShardedJedisPipeline pipeline = jedis.pipelined();
            for (int i : offset) {
                pipeline.setbit(key, i, true);
            }
            
            pipeline.sync();
        }finally{
            if(jedis != null){
                if(connected){
                    pool.returnResource(jedis);
                }else{
                    pool.returnBrokenResource(jedis);
                }
            }
        }
    }     
    
    /**
     * Check if a bizId is part of the set
     * @param key
     * @param bizId
     */
    public boolean include(String key, long bizId){
        int[] offset = HashUtils.murmurHashOffset(bizId, hashFunctionCount, bitSize);
        ShardedJedis jedis = null;
        boolean connected = true;
        try {
            jedis = pool.getResource();
            for (int i : offset) {
                if(!jedis.getbit(key, i)){
                    return false;
                }
            }
        }finally{
            if(jedis != null){
                if(connected){
                    pool.returnResource(jedis);
                }else{
                    pool.returnBrokenResource(jedis);
                }
            }
        }
        
        return true;
    }
    
    /**
     * Check if a bizId is part of the set
     * @param key
     * @param bizId
     */
    public boolean includeWithPipe(String key, long bizId){
        int[] offset = HashUtils.murmurHashOffset(bizId, hashFunctionCount, bitSize);
        ShardedJedis jedis = null;
        boolean connected = true;
        try {
            jedis = pool.getResource();
            ShardedJedisPipeline pipeline = jedis.pipelined();
            for (int i : offset) {
                pipeline.getbit(key, i);
            }
            
            List<Object> responses = pipeline.syncAndReturnAll();
            for (Object object : responses) {
                if(object instanceof Boolean){
                    Boolean contains = (Boolean) object;
                    if(!contains){
                        return false;
                    }
                }
            }
        }finally{
            if(jedis != null){
                if(connected){
                    pool.returnResource(jedis);
                }else{
                    pool.returnBrokenResource(jedis);
                }
            }
        }
        
        return true;
    }
    public long count(String key){
        ShardedJedis jedis = null;
        boolean connected = true;
        try {
            jedis = pool.getResource();
            return jedis.bitcount(key);
        }finally{
            if(jedis != null){
                if(connected){
                    pool.returnResource(jedis);
                }else{
                    pool.returnBrokenResource(jedis);
                }
            }
        }
    }
    
    public String  getRedisData(String key){
        ShardedJedis jedis = null;
        boolean connected = true;
        try {
            jedis = pool.getResource();
            String redisData = jedis.get(key);
            return redisData;
        }finally{
            if(jedis != null){
                if(connected){
                    pool.returnResource(jedis);
                }else{
                    pool.returnBrokenResource(jedis);
                }
            }
        }        
    }
    
    /**
     * Calculate M and K
     * See http://en.wikipedia.org/wiki/Bloom_filter#Probability_of_false_positives for more details
     * @param maxKey
     * @param errorRate
     * @return
     */
    public int calcOptimalM(int maxKey, float errorRate){
        return (int) Math.ceil(maxKey
                * (Math.log(errorRate) / Math.log(0.6185)));
    }
    
    /**
     * Calculate M and K
     * See http://en.wikipedia.org/wiki/Bloom_filter#Probability_of_false_positives for more details
     * @param bitSize
     * @param maxKey
     * @return
     */
    public int calcOptimalK(int bitSize, int maxKey){
        return (int) Math.ceil(Math.log(2) * (bitSize / maxKey));
    }
    
    public String getHosts() {
        return hosts;
    }

    public void setHosts(String hosts) {
        this.hosts = hosts;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public int getMaxKey() {
        return maxKey;
    }

    public void setMaxKey(int maxKey) {
        this.maxKey = maxKey;
    }

    public float getErrorRate() {
        return errorRate;
    }

    public void setErrorRate(float errorRate) {
        this.errorRate = errorRate;
    }

    public int getHashFunctionCount() {
        return hashFunctionCount;
    }

    public void setHashFunctionCount(int hashFunctionCount) {
        this.hashFunctionCount = hashFunctionCount;
    }

    public int getBitSize() {
        return bitSize;
    }

    public void setBitSize(int bitSize) {
        this.bitSize = bitSize;
    }

    /**
     * @param args
     * @throws InterruptedException 
     */
    public static void main(String[] args) throws InterruptedException {
        // TODO Auto-generated method stub
        
        BloomFilter bloomFilter = new BloomFilter(hostConfig, 1000, 0.00000001f, (int)Math.pow(2, 31));
        System.out.println(bloomFilter.getBitSize()/8/1024/2014);
    }

}
Redis亿级数据过滤和布隆过滤器 Redis详解—rehash、布隆过滤器、redis持久化 如上图所示,布隆过滤器(Bloom Filter) 就是这样一种专门用来解决去重问题的高级数据结构。但是跟 HyperLogLog 一样,它也一样有那么一点点不精确,也存在一定的误判概率,但它能在解决去重的同时,在 空间上能节省 90% 以上,也是非常值得的。 布隆过滤器是什么 布隆过滤器(Bloom Filter) 是 1970 年由布隆提出的。它 实际上 是一个很长的二进制向量和一系列随机映射函数 (下面详细说),实际上你也可以把它 简单理解 阅读详情

相关推荐

5分钟搞懂布隆过滤器,掌握亿级数据过滤算法

原文地址:码农在新加坡的个人博客本质上(Bloom Filter)是一种数据结构,比较巧妙的(probabilistic data structure),特点是高效地插入和查询,可以用来告诉你 。相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。可以一句话总结:然后你可能要问了,他都不一定存在了,那它有什么用。 它虽然不保证100%存在,但是这个却是可以控制的,一般根据场景你可以设置一个可以接受的错误率,比如 0.0001(万分之一)

【码农在新加坡】的专栏 2264

第十七章_Redis布隆过滤器BloomFilter实战

使用多个hash函数对key进行hash运算得到一个整数索引值,对位数组长度进行取模运算得到一个位置,每个hash函数都会得到一个不同的位置,将这几个位置都置1就完成了add操作。布隆过滤器的误判是指多个输入经过哈希之后在相同的bit位置1了,这样就无法判断究竟是哪个输入产生的,因此误判的根源在于相同的 bit 位被多次映射且置 1。因为删掉元素会导致误判率增加,因为hash冲突同一个位置可能存的东西是多个共有的,你删除一个元素的同时可能也把其它的删除了。发现存在黑名单中的,就执行特定操作。

sinat_31583645的博客 861

基于Redis的布隆过滤器

基于Redis的布隆过滤器,内含scrapy示例程序,github地址:https://github.com/kongtianyi/BloomFilterRedis

玩转Redis-Redis中布隆过滤器的使用及原理

《玩转Redis》系列文章主要讲述Redis的基础及中高级应用。本文是《玩转Redis》系列第【11】篇,本文关键字:玩转Redis、Bloom filter、布隆过滤器、无偏hash函数; - 布隆过滤器的底层原理 - 布隆过滤器的底层结构 - 最佳hash函数数量与错误率的关系 - 所需存储空间与错误率及容量关系 - 布隆过滤器如何扩容 - 布隆过滤器有哪些应用场景 - 布隆过滤器的优缺点 - 延伸拓展

zxiaofan.com 9242

飞腾D2000 BIOS编译避坑指南:PCIE拆分、S3电源与过温保护配置详解

本文详细解析飞腾D2000 BIOS编译中的关键配置技巧,包括PCIE拆分模式优化、S3电源管理适配及过温保护设置。通过实战案例和参数调优建议,帮助开发者规避常见陷阱,充分发挥国产高性能计算平台的硬件潜力。特别针对BIOS编译过程中的隐蔽问题提供解决方案。

weixin_33704234的博客 535

MIC(Maximal Information Coefficient)最大互信息系数

MIC(Maximal Information Coefficient)最大互信息系数是一种用于衡量两个变量之间相关性的统计量。它扩展了传统的互信息(MI)和条件互信息(CMI)的概念,具有更广泛的应用范围。MIC能够捕获包括功能性和非功能性的广泛的关联,具有普遍性和公平性。普遍性意味着在足够的样本量下,MIC能够捕捉到广泛的相关关系,而不仅仅局限于特定的功能类型;公平性则意味着MIC对不同类型的包含同等噪声的关系给出了相似的分数。需要注意的是,虽然MIC具有很多优点,但它也有一些局限性。

qlkaicx的博客 4606

redis使用布隆过滤器

介绍布隆过滤器以及用法,项目中如何使用,如何解决redis穿透

sora33的博客 1万+

从查表法到实时计算:SimpleFOC库中正弦函数优化的技术演进

本文深入探讨了SimpleFOC库v2.0.1版本中正弦函数优化技术的演进,从传统查表法到实时计算的创新实践。通过定点数优化、对称性利用和分段线性插值等关键技术,实现了在嵌入式电机控制中的高效三角函数计算,显著提升性能和资源利用率。

weixin_28273593的博客 456

SpringBoot + Redis实现布隆过滤器

SpringBoot + Redis布隆过滤器

小小陈的博客 2715

边缘智能新篇章:RK3588上YOLOv8姿态估计的轻量化部署与性能优化实战

本文详细介绍了在RK3588平台上部署和优化YOLOv8姿态估计模型的完整流程。通过模型转换、ONNX中间表示和性能优化策略,实现在边缘设备上的高效实时推理,为嵌入式AI应用提供可行的轻量化解决方案。

ik6789012的博客 154

miRNA测序数据生信分析——第一讲,总结概述

这里的miRNA测序指转录水平的测序。这里每一个数据库都可以在线访问,但是如果要本地使用,都需要进行数据库文件下载,整理。

weixin_44616693的博客 4956

redis 缓存穿透问题,及解决方案

hello~大家好,我是JavaBoy_ahua,好久没有分享redis的知识点啦,记得上次还是整合redis是很简单的一个案例可以说是入了个门吧,这次我要分享的是redis 缓存穿透的一个问题,让大家更深的了解咱们的一个redis。 ok,大家都知道咱们对于一个热点数据,都会进行一个缓存,从而提升我们应用的一个性能,减少我们数据库的一个压力。所以对于热点数据我们都会放在redis中做那么一个缓存,先去redis里面找,没找到再去咱们的数据库。 下面是我话...

gloamer的博客 605

Claude Code与Vibe Coding:2026年AI编程实战指南

AI编程助手是基于大语言模型的智能代码生成工具,通过理解编程上下文提供精准的代码补全和重构建议。其核心原理是利用深度学习技术分析代码语义,将自然语言指令转化为可执行代码。这种技术能显著提升开发效率,减少重复性编码工作,特别适用于快速原型开发和复杂问题求解。在实际应用场景中,AI编程助手可与Vibe Coding方法论结合,建立流畅的人机协作工作流。Claude Code作为先进的AI编程工具,支持多语言开发和智能错误检测,而Vibe Coding则强调自然交互和迭代优化,两者协同为开发者提供完整的AI编程解

weixin_29057695的博客 343

【Redis】应用场景-布隆过滤器(Bloom Filter)

BloomFilter 的算法是,首先分配一块内存空间做 bit 数组,数组的 bit 位初始值全部设为 0。加入元素时,采用 k 个相互独立的 Hash 函数计算,然后将元素 Hash 映射的 K 个位置全部设置为 1。检测 key 是否存在,仍然用这 k 个 Hash 函数计算出 k 个位置,如果位置全部为 1,则表明 key 存在,否则不存在。

精益求精 1153

【Cadence】stb仿真和ac仿真——以一个简单的全差分反相放大器仿真为例

最近在补一些仿真方法学的问题,以及一些一直以来都有点模糊的概念,简单记录一下。搭建一个以两个CMOS反相器构成的全差分放大器(28nm工艺,PMOS和NMOS尺寸一致)激励的设置方便共模和差模仿真用同一个TB(这里有一个问题:这个放大器需要在开环下仿真还是闭环下?哪些放大器应用在开环,哪些闭环?这种应用场景不同会导致需要仿真得到开环还是闭环增益,或者环路增益?(我知道放大器在设计的时候肯定都是闭环应用的多,但是什么时候没必要闭环应用?光验证ac和stb仿真是否一样的话有必要有回路吗?

weixin_44951108的博客 5万+

LSTM 双向 Bi-LSTM

LSTM 双向 Bi-LSTM

jacke121的专栏 1519

python模块之redisbloom redis布隆过滤器

RedisBloom 是一个 Redis 模块,提供了布隆过滤器(Bloom Filter)、计数器(Count-Min Sketch)、Top-K(Top-K)、Top-K with expiry(Top-K with Expiration)和多样本(Cuckoo Filter)等数据结构的实现。它通过将这些数据结构存储在 Redis 中,为应用程序提供了高效的数据处理和查询功能。布隆过滤器(Bloom Filter):布隆过滤器是一种高效的数据结构,用于快速判断一个元素是否存在于集合中。

老衲爱洗头的博客 1065

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

Redis安装布隆过滤器

目录 1 什么是布隆过滤器 1.1 布隆过滤器的原理 1.2 布隆过滤器缺点 2 插件形式安装 2.1 下载布隆过滤器插件 3 docker方式单机安装 4 Redis集群部署安装 4.1 创建目录 4.2 redis配置文件 4.3 配置docker-compose.yml文件 4.4 启动布隆过滤器集群 4.5 配置集群 4.6 布隆过滤器常用命令 4.7 测试

赵广陆 1404

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

实现的redis布隆过滤器_使用redis创建布隆过滤器

布隆过滤器是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。但是布隆过滤器可以控制错误率。具体的布隆过滤器相关的内容可查找相关资料,非常详细,其优势就是占用内存比hash表要小得多,非常适合用于做过滤的场景Guava中的布隆过滤器Guava是google开发的java基础...

weixin_27372101的博客 1548

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

BloomFilter:布隆过滤器和Redis缓存穿透

BloomFilter,中文名叫布隆过滤器,用于判断目标值是否存在。

超频化石鱼的博客 442

python或Redis实现简单布隆过滤器 BloomFilter

## 简介 通过较少的空间,不存储数据本身而存储通过hash函数映射的位向量表,以此作为判断一个值是否存在的依据。BloomFilter只能确保一个值一定不存在,判断存在的情况由于位向量表有限以及hash表也可能产生冲突,并不准确,有一定误判的几率。 ![布隆过滤器](https://z3.ax1x.com/2021/08/09/f8mwX6.md.png) 红色和蓝色是成功添加了的数据,经过多个哈希函数映射后,位向量中对应的位被置为1。 需要判断黄色是否已经存在,经过同样多个hash函..

milanla的博客 1252

Redis的缓存问题:缓存穿透、缓存击穿和缓存雪崩

Key对应的书在数据源并不存在,每次针对此key的请求从缓存获取不到,请求都会到压到数据库,从而可能压垮数据源比如:一个不存在的用户id,获取用户信息,不论缓存还是数据库都没有,若黑客利用此漏洞进行攻击可能会压垮数据库。

echola_mendes的博客 1480

Redis缓存穿透、缓存击穿、缓存雪崩

1、基本概念 2、缓存穿透解决方案 缓存空对象(代码接单,效果不好),导致大量的空对象数据 布隆过滤器(代码复杂,效果很好,一般使用这个) 原理 手写分布式的布隆过滤器 ①、比如根据用户ID查询用户的信息 public RestResponse<User> getUserInfo(String userId) { //缓存空对象(代码接单,效果不好),导致大量的空对象数据 //先查询redis缓存 Object redisUser =

liangshitian的博客 539

redis工具包开发——功能概览

这篇文章主要是介绍功能点,先看看这个工具包有什么可以用的,目前主要有两个模块——布隆过滤器、基于注解限流。基于redisTemplate 用法: 这里用maven作为工具管理包演示,添加jitpack源、添加下面的依赖 <repositories> <repository> <id>jitpack.io&l...

(づ ̄ 3 ̄)づxl 1080

高可用服务设计|如何应对缓存穿透|玩转布隆过滤器

一、背景 用户中心是授权逻辑与用户信息相关逻辑构建的应用。分布式系统中,大多数业务都需要和用户中心打交道,为了保证用户中心服务的高可用,避免不了做缓存、导入搜索引擎从而降低数据库的压力。然而有些不经过用户中心授权的业务场景查询用户中心的数据,可能引发大量无效的查询,发生缓存穿透,直接对搜索引擎和数据库造成压力。如何解决用户中心缓存穿透的问题呢?接下来就着重说一下布隆过滤器是怎么“隔档”这些无效查询...

胡峻峥的博客 412

分布式爬虫去重:Python + Redis实现高效URL去重

通过合理选择方案,可以显著提升爬虫效率,避免重复抓取。如果不对URL进行去重,爬虫可能会重复抓取相同页面,导致资源浪费、数据冗余,甚至触发目标网站的反爬机制。节省内存,但有一定误判率(可能误判未访问的URL为已访问),适用于海量URL去重。环境下,多个爬虫节点同时工作时,内存级的去重方式不再适用。最简单的去重方式,适用于小规模数据,但无法持久化,重启后数据丢失。:数据存储在内存中,读写速度极快(10万+ QPS)。类似Redis,但功能较少,通常仅用于缓存。结构存储URL,精确去重(100%准确)。

Z_suger7的博客 1305
上一篇: Nginx限流、缓存、黑白名单等
下一篇: Sentinel使用令牌桶实现预热和原理
yonhu123java
博客等级 码龄14年 6粉丝 47原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值