如何在海量数据中判断某条记录是否存在-布隆过滤器的使用(JDK版和Redis版)

场景

  • 爬虫时判断某个URL是否已经被爬取过
  • 黑名单过滤
  • 防止缓存穿透

实现原理

定义一个长度为m的bit型数组flag[] (用来添加元素以及判断元素是否存在,因为Integer的最大值为2147483647,所以m取该值即可)
定义n个不同的hash函数(在添加元素时,需要设置flag[]哪些位为1; 在判断元素是否存在时,需要取flag[]哪些位来判断)
添加某个元素时,通过n个hash函数算出该元素的n个hash值(整型值),把flag[]对应的位置1
判断某个元素是否存在时,通过n个hash函数算出该元素的n个hash值(整型值),在flag[]取出对应的值,只要有一个不为1 ,即可判断为不存在.否则就任务元素存在

布隆过滤器优缺点

优点: 大大节省空间

场景: 在10亿数据中判断某个数据是否存在
如果使用HashSet/HashMap来实现的话
查找的时间复杂度是O(1),但是我们来算一下存储空间,Hash值为Integer类型,占四个字节,那10亿条数据占用的空间就是:10亿*4/1024/1024/1024约等于3.7G…这个实现方案很明显不现实
如果使用布隆过滤器实现
占用的空间大约为2147483647/8/1024/1024=256M

缺点: 误差

由上面的分析可知, hash函数是存在hash冲突的, 所以布隆过滤器是会有误判的情况.
表现为:

如果某条记录被判断为不存在,则该记录必然不存在
如果某条记录被判断存在,则该记录可能会不存在

代码实现

JDK版
public class BloomFilterDemo {

    private static final int insertions = 1000000;

    @Test
    public void bfTest1(){
        //初始化一个存储string数据的布隆过滤器,初始化大小100w,不能设置为0
        BloomFilter<String> bf = BloomFilter.create(Funnels.stringFunnel(Charsets.UTF_8), insertions,0.001);
        //初始化一个存储string数据的set,初始化大小100w
        Set<String> sets = new HashSet<>(insertions);
        //初始化一个存储string数据的set,初始化大小100w
        List<String> lists = new ArrayList<>(insertions);

        //向三个容器初始化100万个随机并且唯一的字符串---初始化操作
        for (int i = 0; i < insertions; i++) {
            String uuid = UUID.randomUUID().toString();
            bf.put(uuid);
            sets.add(uuid);
            lists.add(uuid);
        }
        //布隆过滤器错误判断的次数
        int wrong = 0;
        //布隆过滤器正确判断的次数
        int right = 0;
        for (int i = 0; i < 10000; i++) {
            //按照一定比例选择bf中肯定存在的字符串
            String test = i%100==0?lists.get(i/100):UUID.randomUUID().toString();
            if(bf.mightContain(test)){
                if(sets.contains(test)){
                    right ++;
                }else{
                    wrong ++;
                }
            }
        }

        //100
        System.out.println("=================right=====
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis布隆过滤器是一种基于布隆过滤器实现的数据结构,它可以用于高效地判断一个元素是否存在于集合。在Redis,通过使用BITMAPS和HASHES命令来实现布隆过滤器。 要使用Redis布隆过滤器,首先需要在Redis服务器上安装和配置Redis,并确保已经加载了布隆过滤器模块。然后,可以使用BF.ADD命令将元素添加到布隆过滤器使用BF.EXISTS命令查询元素是否存在布隆过滤器Redis布隆过滤器使用相对简单,但也存在一些注意事项。由于布隆过滤器是基于概率的数据结构,存在一定的误判率。为了减少误判率,可以增加二进制数组的位数或增加哈希次数。此外,由于布隆过滤器是基于内存的数据结构,需要确保Redis服务器具有足够的内存来存储布隆过滤器。 总之,通过安装和配置Redis服务器,并使用BF.ADD和BF.EXISTS命令,可以轻松地在Redis使用布隆过滤器判断元素是否存在于集合。但需要注意误判率和内存需求等因素。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [redis使用布隆过滤器](https://blog.csdn.net/qq_40179653/article/details/125716731)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [Python+Redis实现布隆过滤器](https://download.csdn.net/download/weixin_38751905/14912053)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值