zoukankan      html  css  js  c++  java
  • 布隆过滤器在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运算,将运算结果和位数组的长度取模,然后在对应的位置查看是否有相应的数据,如果有,表示元素可能存在(因为有可能是其他元素存进来的),如果没有,那就一定没有。

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

    安装:

       安装完成后,如果 bf.add命令有提示的话,就表示安装成功。
    基本用法:
        主要两个命令:添加和判断
    bf.addf.madd(添加和批量添加)
    bf.existsf.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, 
    "zl");
            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 中不现实,但是可以存
    在布隆过滤器中,请求来了,首先去判断数据是否存在,如果存在,再去数据库中查询,否则就不去数据库中查询。
     
     
     
  • 相关阅读:
    java--递归删除目录
    java--获取文件夹大小
    我经历中最重要的三位老师
    我的自我介绍
    如何判断多选框是否选中?
    控制总线 数据总线和地址总线是三根线吗
    单元格中间没有边框
    页面上插入bootstrap Glyphicons时遇到的问题
    浏览器回退键——重复提交
    【excel】excel转成csv乱码问题
  • 原文地址:https://www.cnblogs.com/javazl/p/12665192.html
Copyright © 2011-2022 走看看