Redis 布隆过滤器的原理和实践教程

 更新时间:2024年03月05日 10:07:22   作者:格林希尔  
布隆过滤器适用于需要快速判断一个元素是否可能存在于集合中的场景,例如网络爬虫中的去重、缓存中的数据判断等,这篇文章主要介绍了Redis 布隆过滤器的原理和实践,需要的朋友可以参考下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

背景介绍

  布隆过滤器可以帮助我们解决Redis缓存雪崩的问题,那什么是布隆过滤器、布隆过滤器又是如何使用如何解决缓存雪崩的问题的,让我们带着这一系列的问题去详细了解布隆过滤器。

概念说明

  布隆过滤器是一种用于快速判断一个元素是否属于一个集合的数据结构。它通常用于大规模数据集合中,可以快速判断一个元素是否可能存在于集合中,但不能确定一定存在。布隆过滤器的主要优点是占用内存少、查询速度快,并且可以容忍一定的误判率。

Redis 布隆过滤器的原理和实践

一、简介

1 布隆过滤器的定义

布隆过滤器是一种空间效率高、误判率可控的数据结构,通常用于检索一个元素是否在一个集合中。它是由一个比特向量和多个哈希函数组成的。布隆过滤器可以用于快速检测一个元素是否存在于一个集合中,其主要优点是省内存缺点是有一定的误识别率和删除困难。

2 Redis 布隆过滤器的特点

  • Redis 布隆过滤器采用了 Redis 自身的数据结构实现,支持数据持久化,重启后依然有效
  • 在 Redis 中使用布隆过滤器需要先安装 RedisBloom 模块
  • Redis 布隆过滤器使用多个哈希函数,并使用不同的随机种子在一定程度上降低了误判率
  • Redis 布隆过滤器可以设置错误率和元素数量通过调整这些参数可以控制误判率

3 Redis 布隆过滤器的应用场景

  • 邮箱黑名单、敏感词过滤
  • 在搜索引擎中过滤掉爬虫或者恶意软件等
  • 在数据库中避免重复插入相同数据
  • 在网站访问中,可以使用布隆过滤器缓存那些已经访问过的页面

二、原理分析

1 布隆过滤器的基本原理

假设哈希函数个数为 k 每个比特位被设置多少次记为 m,n 为元素数量,则误判率为 (1 - e(-kn/m))^k。当误判率为 p 时选取最优的哈希函数个数 k 和比特位长度 m 可以使空间利用更加高效

代码示例

public class BloomFilter {
    private int size;
    private int[] hashes;
    private BitSet bits;
    public BloomFilter(int size, int[] hashes) {
        this.size = size;
        this.hashes = hashes;
        this.bits = new BitSet(size);
    }
    public void add(String value) {
        for (int hash : hashes) {
            int position = Math.abs(value.hashCode() * hash) % size;
            bits.set(position, true);
        }
    }
    public boolean contains(String value) {
        for (int hash : hashes) {
            int position = Math.abs(value.hashCode() * hash) % size;
            if (!bits.get(position)) {
                return false;
            }
        }
        return true;
    }
}

2 布隆过滤器的实现原理

  • 创建 Redis 布隆过滤器时需要指定误判率和预期元素数量,Redis 客户端会根据这些参数计算出最优的比特位长度 m 和哈希函数个数 k。
  • Redis 使用 MurmurHash2 和 MurmurHash64A 两个哈希函数计算各自的哈希值,来保证布隆过滤器的误判率和运行效率。
  • 将插入元素在 k 个哈希函数中生成对应的 k 个哈希值,并将比特向量的这些位置置为 1。
  • 查找元素是同样地使用 k 个哈希函数计算出 k 个哈希值,在比特向量的对应位置查找是否都为 1。

代码示例

Jedis jedis = new Jedis("localhost", 6379);
jedis.getClient().sendCommand(BloomFilterCommands.RESERVE, "mybloom", "0.001", "100000");
jedis.getClient().sendCommand(BloomFilterCommands.ADD, "mybloom", "hello");
Response<Boolean> response = jedis.getClient().getBooleanReply();
response.get();
jedis.getClient().sendCommand(BloomFilterCommands.EXISTS, "mybloom", "hello");
Response<Boolean> response = jedis.getClient().getBooleanReply();
response.get();

3 布隆过滤器的优化策略

  • 增加哈希函数的数量可以降低误判率,但同时也会增加空间复杂度和计算时间
  • 确定适当的预期元素数量和误判率,避免过拟合和欠拟合
  • 在 Redis 集群中,布隆过滤器可以通过将多个小的布隆过滤器组成一个大的布隆过滤器来协同工作,提高并发处理能力和存储效率

三、Redis 布隆过滤器的实践

1 布隆过滤器的安装和配置

Redis 布隆过滤器需要在 Redis 中进行安装和配置才能够使用。首先需要在 Redis 安装目录下的 src 文件夹中找到 redis-trib.rb 文件。

# 进入 Redis 安装目录
cd xxx/redis-xx
# 执行以下命令安装 Redis 布隆过滤器
ruby src/redis-trib.rb create --replicas 1 ip:port ip:port ip:port ...

在上述命令中ip:port 需要替换为 Redis 节点的 IP 地址和端口号

2 布隆过滤器的使用方法

Redis 布隆过滤器常用于判断某个元素是否在集合中可以通过以下命令进行使用:

# 向布隆过滤器添加元素
BF.ADD key element [element ...]
# 判断元素是否在布隆过滤器中
BF.EXISTS key element

其中,key 表示 Redis 的键名,element 表示需要添加或判断的元素。

3 布隆过滤器的性能测试和优化

Redis 布隆过滤器可以通过以下命令来进行性能测试:

# 测试添加元素的速度
BF.RESERVE key 0.0001 10000
# 测试判断元素是否在布隆过滤器中的速度
BF.EXISTS key element

需要注意的是在 BF.RESERVE 命令中,第一个参数 key 代表 Redis 的键名,第二个参数为错误率即误报的概率,第三个参数代表预期最大元素个数。

如果发现 Redis 布隆过滤器性能较低,可以通过增加节点个数或降低错误率等方式进行优化。

四、Redis 布隆过滤器的应用案例

1 布隆过滤器在网站防刷中的应用

Redis 布隆过滤器可以用于网站的防刷功能,通过判断IP地址或者用户行为是否已经超出一定的次数来避免短时间内多次请求相同的资源。例如:

# 判断 IP 地址是否已经被封禁
if BF.EXISTS ip_bloom_filter ip {
    return 403; # 返回禁止访问的状态码
}

2 布隆过滤器在数据去重中的应用

在数据去重方面可以使用 Redis 布隆过滤器来避免在大规模数据处理中的重复计算,减少计算开销,并且保证数据的唯一性

# 判断文章是否已经被处理过
if BF.EXISTS article_bloom_filter article_id {
    continue; # 跳过本次循环
}
# 处理文章内容
process_article(article);
# 将文章 ID 添加到布隆过滤器中
BF.ADD article_bloom_filter article_id;

3 布隆过滤器在爬虫去重中的应用

在爬虫系统中为了避免重复爬取已经存在的网页,可以使用 Redis 布隆过滤器来记录已经访问过的 URL

# 判断 URL 是否已经被访问过
if BF.EXISTS url_bloom_filter url {
    continue; # 跳过本次循环
}
# 访问 URL
response = http.get(url);
# 将 URL 添加到布隆过滤器中
BF.ADD url_bloom_filter url;

通过以上的应用案例可以看出Redis 布隆过滤器具有在数据去重、防刷、爬虫去重等方面的广泛应用,并且可以有效地减少重复计算、避免误报或者漏报等问题。

五、Redis 布隆过滤器的优缺点分析

1 布隆过滤器的优点

  • 布隆过滤器是一种空间效率高的数据结构可以代替传统的 List, Set 等数据结构,以达到节约内存的目的
  • 布隆过滤器的插入和查询时间复杂度都是 O(k),k 是哈希函数个数,这个值可以根据数据量去调整,因此查询效率非常高。
  • 布隆过滤器可以用于判断一个元素是否在集合中,可以用在缓存穿透的场景中。

2 布隆过滤器的缺点

  • 布隆过滤器无法删除元素,一旦添加了一个元素就无法删除,因为删除可能会影响其他元素的判断结果
  • 布隆过滤器的误判率是存在的,这是由于多个元素映射到布隆过滤器的同一个位置,使得可能存在“误判”情况
  • 布隆过滤器的哈希函数个数和大小都需要事先确定,这在一些应用场景中可能不太容易确定。

3 布隆过滤器的适用场景

  • 缓存穿透:如果缓存中不存在某个键对应的值,而且大量的请求又同时访问该键,这时可以通过布隆过滤器过滤掉这些非法请求,降低了对后端系统的压力。
  • 网络爬虫:利用布隆过滤器判断一个链接是否已经被爬取过,避免重复抓取同一链接,提高爬虫的效率。
  • 黑名单过滤:将不良网址、IP 地址等加入到布隆过滤器中,当请求过来时直接使用布隆过滤器判断是否需要过滤掉该请求。

到此这篇关于Redis 布隆过滤器的原理和实践的文章就介绍到这了,更多相关Redis布隆过滤器内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • redis保存session信息的示例代码

    redis保存session信息的示例代码

    本文实现一个将session信息保存在 redis中,多个tomcat中的工程都从redis获取session信息的示例,本文给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2023-01-01
  • Redis序列化转换类型报错的解决

    Redis序列化转换类型报错的解决

    本文主要介绍了Redis序列化转换类型报错的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-04-04
  • Redis分布式缓存:微信抢红包解决方案

    Redis分布式缓存:微信抢红包解决方案

    微信抢红包已经在我们生活中很常见的场景了,特别是年底公司开年会和春节2个时间段。本文主要介绍了通过Redis实现微信抢红包功能,感兴趣的小伙伴可以了解一下
    2021-12-12
  • Redis去重的3种不同方法汇总

    Redis去重的3种不同方法汇总

    Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库,下面这篇文章主要给大家介绍了关于Redis去重的3种不同方法,需要的朋友可以参考下
    2021-11-11
  • redis底层数据结构之ziplist实现详解

    redis底层数据结构之ziplist实现详解

    这篇文章主要为大家介绍了redis底层数据结构之ziplist实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • 基于Redis无序集合如何实现禁止多端登录功能

    基于Redis无序集合如何实现禁止多端登录功能

    这篇文章主要给你大家介绍了关于基于Redis无序集合如何实现禁止多端登录功能的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-12-12
  • Redis Stat的安装指南

    Redis Stat的安装指南

    这篇文章主要介绍了Redis Stat的安装指南的相关资料,需要的朋友可以参考下
    2016-04-04
  • Redis数据结构之链表详解

    Redis数据结构之链表详解

    大家好,本篇文章主要讲的是Redis数据结构之链表详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2021-12-12
  • redis?setIfAbsent返回null的问题及解决

    redis?setIfAbsent返回null的问题及解决

    这篇文章主要介绍了redis?setIfAbsent返回null的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Redis中键的过期删除策略深入讲解

    Redis中键的过期删除策略深入讲解

    这篇文章主要给大家介绍了关于Redis中键的过期删除策略的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09

最新评论

?


http://www.vxiaotou.com