[TOC]
> **RedisBloom** 为 Redis 添加了四种概率数据结构:可扩展的**布隆过滤器**、**布谷鸟过滤器**、**count-min sketch**和**top-k**。
> **布隆过滤器**和**布谷鸟过滤器**用于高度确定地确定一个元素是否是集合的成员。
> 官网 https://redis.io/docs/stack/bloom
## 安装 RedisBloom 模块
~~~sh
git clone --recursive https://github.com/RedisBloom/RedisBloom.git
cd RedisBloom
make setup
make
~~~
## **布隆过滤器**
* 由一个初值都为零的 bit 数组和多个哈希函数构成,用来快速判断某个数据是否存在
* 本质就是判断具体数据存不存在一个大的集合中
* 布隆过滤器类似 `set` 的数据结构,只是统计结构不太准确
### 应用场景
* 垃圾邮件过滤
* 文字处理中的错误单词检测
* 网络爬虫重复URL检测
* 会员抽奖
* 判断一个元素在亿级数据中是否存在
* 缓存穿透
### 原理
布隆过滤器(Bloom Filter) 是一种专门用来解决去重问题的高级数据结构。 实质就是一个大型**位数组和几个不同的无偏hash函数 **(无偏表示分布均匀)。**由一个初值都为零的bit数组和多个个哈希函数构成**,用来快速判断某个数据是否存在 。但是跟 HyperLogLog 一样,它也一样有那么一点点不精确,也存在一定的误判概率。
### **添加key**
使用多个 hash 函数对 key 进行 hash 运算得到一个整数索引值,对位数组长度进行取模运算得到一个位置,每个hash 函数都会得到一个不同的位置,将这几个位置都置 1 就完成了 add 操作。
### **查询key**
先把这个 key 通过相同的多个 hash 函数进行运算,查看对应位置不都为 1
如果这些点,**有任何一个为 0 则被查询变量一定不在,如果都是 1,则被查询变量很 可能存在**
**为什么说是可能存在,而不是一定存在呢?**`那是因为映射函数本身就是散列函数,散列函数是会有碰撞的。`
![布隆过滤器原理图](https://img.kancloud.cn/e7/50/e7504b414ea3b03460485a63174f9582_1002x716.png)
### 误判率,为什么不能删除元素
误判是指多个输入经过 hash 之后在相同 bit 位置为1 了,这样就无法判断究竟是哪个输入所产生的,**误判的根源在于相同的 bit 位被多次映射且置 1。 **
**布隆过滤器的每一个 bit 并不是独占的,很有可能多个元素共享了某一位**如果删除一位,或影响其他元素。
### 基本命令
~~~sh
127.0.0.1:6379> bf.reserve bf 0.1 10 # 创建一个空的布隆过滤器 错误率0.1 容量10(超出10以后性能下降)。错误率越小,需要的空间越大
OK
127.0.0.1:6379> bf.add bf a # 添加项
(integer) 1
127.0.0.1:6379> bf.add bf a
(integer) 0
127.0.0.1:6379> bf.madd bf b c d e # 添加多个项
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 1
127.0.0.1:6379> bf.madd bf e f g h i j
1) (integer) 0
2) (integer) 1
3) (integer) 1
4) (integer) 1
5) (integer) 1
6) (integer) 1
127.0.0.1:6379> bf.exists bf c # 项是否存在 1:可能存在、0:一定不存在
(integer) 1
127.0.0.1:6379> bf.exists bf q
(integer) 0
127.0.0.1:6379> bf.mexists bf a d h l
1) (integer) 1
2) (integer) 1
3) (integer) 1
4) (integer) 0
~~~
更多命令:https://redis.io/commands/?name=bf.
### 优缺点
#### **优点:**
* 高效得插入和查询,占用空间少
#### **缺点:**
* 不能删除元素
* 存在误判,不同的数据可能出来相同的hash值
## 杜鹃过滤器
**解决了布隆过滤器不能删除元素的问题**
~~~sh
127.0.0.1:6379> cf.reserve cf 10 # 创建一个具有初始容量(10个项目)的空杜鹃过滤器
OK
127.0.0.1:6379> cf.add cf a
(integer) 1
127.0.0.1:6379> cf.exists cf a
(integer) 1
127.0.0.1:6379> cf.add cf b
(integer) 1
127.0.0.1:6379> cf.add cf c
(integer) 1
127.0.0.1:6379> cf.del cf a # 删除过滤器中项目
(integer) 1
~~~
更多命令:https://redis.io/commands/?name=cf.
- PHP
- PHP 核心架构
- PHP 生命周期
- PHP-FPM 详解
- PHP-FPM 配置优化
- PHP 命名空间和自动加载
- PHP 运行模式
- PHP 的 Buffer(缓冲区)
- php.ini 配置文件参数优化
- 常见面试题
- 常用函数
- 几种排序算法
- PHP - 框架
- Laravel
- Laravel 生命周期
- ThinkPHP
- MySQL
- 常见问题
- MySQL 索引
- 事务
- 锁机制
- Explain 使用分析
- MySQL 高性能优化规范
- UNION 与 UNION ALL
- MySQL报错:sql_mode=only_full_group_by
- MySQL 默认的 sql_mode 详解
- 正则表达式
- Redis
- Redis 知识
- 持久化
- 主从复制、哨兵、集群
- Redis 缓存击穿、穿透、雪崩
- Redis 分布式锁
- RedisBloom
- 网络
- 计算机网络模型
- TCP
- UDP
- HTTP
- HTTPS
- WebSocket
- 常见几种网络攻击方式
- Nginx
- 状态码
- 配置文件
- Nginx 代理+负载均衡
- Nginx 缓存
- Nginx 优化
- Nginx 配置 SSL 证书
- Linux
- 常用命令
- Vim 常用操作命令
- Supervisor 进程管理
- CentOS与Ubuntu系统区别
- Java
- 消息队列
- 运维
- RAID 磁盘阵列
- 逻辑分区管理 LVM
- 业务
- 标准通信接口设计
- 业务逻辑开发套路的三板斧
- 微信小程序登录流程
- 7种Web实时消息推送方案
- 用户签到
- 用户注册-短信验证码
- SQLServer 删除同一天用户重复签到
- 软件研发完整流程
- 前端
- Redux
- 其他
- 百度云盘大文件下载
- 日常报错记录
- GIT
- SSL certificate problem: unable to get local issuer certificate
- NPM
- reason: connect ECONNREFUSED 127.0.0.1:31181
- SVN
- SVN客户端无法连接SVN服务器,主机积极拒绝
- Python
- 基础
- pyecharts图表
- 对象
- 数据库
- PySpark
- 多线程
- 正则
- Hadoop
- 概述
- HDFS