基于redis 实现布隆过滤器

探讨了如何利用Redis的Bitmap数据结构结合布隆过滤器进行高效URL去重,对比了使用set()方法的内存消耗,展示了通过哈希函数与取模运算填充Bitmap的具体实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

简介

Redis中有一个数据结构叫做Bitmap(下方有官网详解),它提供一个最大长度为512MB(2^32)的位数组。我们可以把它提供给布隆过滤器做位数组。

根据《数学之美》中给出的数据,在使用8个哈希函数的情况下,512MB大小的位数组在误报率万分之五的情况下可以对约两亿的url去重。而若单纯的使用set()去重的话,以一个url64个字节记,两亿url约需要128GB的内存空间,不敢想象。

我使用的策略是使用哈希函数算出的哈希值对2^32取模,填入bitmap中。
 

本文主要是介绍这种思想和用法,具体业务使用过程中,需要具体实现,下面贴出代码 演示最简单的一种使用方法:

/*
	 * 模拟项目启动时候 从"数据库"或者其他地方获取到的过滤器集合的数据
	 */
	static List<String> l = new ArrayList<String>();

	// 模拟生成的订单号/用户/商品ID
	static {
		l.add("201810120001");
		l.add("201810120002");
		l.add("201810120003");
		l.add("201810120004");
	}

	/**
	 * 单机版测试
	 */
	@Test
	public void TestRedis() {
		Jedis jedis = new Jedis("192.168.1.118", 6379);

		// 获取redis支持的最大长度作为取模的基数
		double size = Math.pow(2, 32);
		// 循环l 取出里面的数据,放入到redis中
		l.forEach(orderId -> {
			long index = Math.abs((long) (orderId.hashCode() % size));
			jedis.setbit("orderId", index, true);
		});
		
		

		// 判断指定值是否在过滤器里面
		String orderId = l.get(0);
		//String orderId = "201810120005";
		long index =  Math.abs((long) (orderId.hashCode() % size));
		boolean contain = jedis.getbit("orderId", index);
		// 为true 说明在里面
		if (contain) {
			System.out.println("包含这个值.");
			// 否则不在
		} else {
			System.out.println("不包含这个值.");
		}


		jedis.close();
	}

运行结果 orderId如果在l集合里面 就显示包含,否则就不包含

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值