------------------------------------------------------------------------------------------------------慢慢来,一切都来得及
介绍
布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都远远超过一般的算法,缺点是有一定的误识别率和删除困难。
布隆过滤器被广泛用于网页黑名单系统、垃圾邮件过滤系统、爬虫的网址判重系统以及解决缓存穿透问题。通过介绍已经知晓布隆过滤器的作用是检索一个元素是否在集合中。可能有人认为这个功能非常简单,直接放在redis中或者数据库中查询就好了。又或者当数据量较小,内存又足够大时,使用hashMap或者hashSet等结构就好了。但是如果当这些数据量很大,数十亿甚至更多,内存装不下且数据库检索又极慢的情况,我们应该如何去处理?这个时候我们不妨考虑下布隆过滤器,因为它是一个空间效率占用极少和查询时间极快的算法,但是需要业务可以忍受一个判断失误率。当布隆过滤器说某个值存在时,这个值可能不存在;当它说不存在时,那就肯定不存在。
基本使用
布隆过滤器有二个基本指令,bf.add 添加元素,bf.exists 查询元素是否存在,它的用法和 set 集合的 sadd 和 sismember 差不多。注意 bf.add 只能一次添加一个元素,如果想要一次添加多个,就需要用到 bf.madd 指令。同样如果需要一次查询多个元素是否存在,就需要用到 bf.mexists 指令。
降低误判率
Redis 其实还提供了自定义参数的布隆过滤器,需要我们在 add 之前使用 bf.reserve指令显式创建。如果对应的 key 已经存在,bf.reserve 会报错。bf.reserve 有三个参数,分别是 key, error_rate 和 initial_size。错误率越低,需要的空间越大。initial_size 参数表示预计放入的元素数量,当实际数量超出这个数值时,误判率会上升。所以需要提前设置一个较大的数值避免超出导致误判率升高。如果不使用 bf.reserve,默认的 error_rate 是 0.01,默认的 initial_size 是 100。
布隆过滤器的 initial_size 估计的过大,会浪费存储空间,估计的过小,就会影响准确率,用户在使用之前一定要尽可能地精确估计好元素数量,还需要加上一定的冗余空间以避免实际元素可能会意外高出估计值很多。布隆过滤器的 error_rate 越小,需要的存储空间就越大,对于不需要过于精确的场合,error_rate 设置稍大一点也无伤大雅。