基于redis 实现布隆过滤器

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u013278314/article/details/83027781

简介

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集合里面 就显示包含,否则就不包含

猜你喜欢

转载自blog.csdn.net/u013278314/article/details/83027781