布隆过滤器在redis中的使用

简介:

布隆过滤器是一种实现去重的思想,不属于redis,它也可以在其他地方单独使用。

布隆过滤器也是做去重的,那和Hyperloglog有什么区别.

Hyperloglog用来来估值,有偏差,它里面主要提供了两个方法:

  1. pfadd
  2. pfcount

       但是没有判断是否包含的命令,例如pfexist,pfcontains这样的命令。举个例子:在刷进入头条的时候,每次推送的内容都相似,但都不一样,那有什么解决方案呢?,可以将每个用户的浏览历史记录下来,然后每次推送的时候去判断,但是这种的在高并发,数据量很大的时候就不适用。因此这里可以使用布隆过滤器去处理。

        bloom Filter:是专门用来做去重操作的,它相比于缓存的话,它不那么浪费空间,但是和Hyperloglog一样都是不太精确的,但是这个精确度可以自己调节。当数据量小的时候,精确度高一点,占用的空间就多,当数据量很大的时候,可以把精确度调低一点,这样占用的空间就小一点。

        bloom Filter相当于一个不太精确的set集合,我们可以使用contains方法去判断某个对象是否存在,但是这个判断不太精确,当判断不存在的时候 ,他一定不存在,当判断它存在的时候,它不一定存在。以今日头条为例,假设我们将用户的浏览记录用 B 表示,A 表示用户没有浏览的新闻,现在要给用户推送消息,先去 B 里边判断这条消息是否已经推送过,如果判断结果说没推送过(B 里边没有这条记录),那就一定没有推送过。如果判断结果说有推送过(B 里边也有可能没有这条消息),这个时候该条消息就不会推送给用户,导致用户错过该条消息。

原理:

     每个布隆过滤器就相当于一个大型的位数组,和几个不同的hash函数。

      所谓add操作,就是根据几个不同的hash函数元素进行hash算出一个整数索引值,拿到这个索引值后,对维数组进行取模运算,得到一个位置,每个hash函数都会得到一个位置,将位数组中对应的位置设置为1,这样就完成添加操作。

      当判断元素是否存在的时候,依然对元素先进行hash运算,将运算结果和位数组的长度取模,然后在对应的位置查看是否有相应的数据,如果有,表示元素可能存在(因为有可能是其他元素存进来的),如果没有,那就一定没有。

扫描二维码关注公众号,回复: 10620490 查看本文章

      误判的概率和位数组的大小有关,位数组越大,误判概率越小,所占用的空间就越大。

安装:

   安装完成后,如果 bf.add命令有提示的话,就表示安装成功。
基本用法:
    主要两个命令:添加和判断
bf.add\bf.madd(添加和批量添加)
bf.exists\bf.mexists(判断和批量判断)
使用jedis操作布隆过滤器:
1.添加依赖(jrebloom)
2.测试:
public class BloomFilter {
    public static void main(String[] args) {
        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxIdle(300);
        config.setMaxTotal(1000);
        config.setMaxWaitMillis(30000);
        config.setTestOnBorrow(true);
        JedisPool pool = new JedisPool(config, "192.168.91.128", 6379, 30000, 
"javaboy");
        Client client = new Client(pool);
        //存入数据
        for (int i = 0; i < 100000; i++) {
            client.add("name", "zl-" + i);
       }
        //检查数据是否存在
        boolean exists = client.exists("name", "zl-9999999");
        System.out.println(exists);
   }
}

      默认布隆过滤器的错误率是0.01,默认元素的大小为100,当然也可以存超过100个,只不过错误率会上升。

这两个参数可以去配置的:bf.reserve

应用场景:

新闻推送过滤

解决redis穿透,或者缓存击穿问题

假设我有 1亿 条用户数据,现在查询用户要去数据库中查,效率低而且数据库压力大,所以我们会把请
求首先在 Redis 中处理(活跃用户存在 Redis 中),Redis 中没有的用户,再去数据库中查询。
现在可能会存在一种恶意请求,这个请求携带上了很多不存在的用户,这个时候 Redis 无法拦截下来请
求,所以请求会直接跑到数据库里去。这个时候,这些恶意请求会击穿我们的缓存,甚至数据库,进而
引起“雪崩效应”。
为了解决这个问题,我们就可以使用布隆过滤器。将 1亿条用户数据存在 Redis 中不现实,但是可以存
在布隆过滤器中,请求来了,首先去判断数据是否存在,如果存在,再去数据库中查询,否则就不去数据库中查询。
 
 
 

猜你喜欢

转载自www.cnblogs.com/javazl/p/12665192.html