-
安装使用
- rebloom作为插件安装 centos安装rebloom
- docker安装:
// 拉取镜像 docker pull redislabs/rebloom // 后台运行,映射到本地6380端口 docker run -d -p 6380:6379 redislabs/rebloom // 连接 redis-cli -p 6380
-
布隆过滤器的主要命令和误判
- bf.add: 语法:[bf.add key value] 返回1添加成功
- bf.exists: 语法:[bf.exists key value] 返回1表示存在
- madd, mexists是添加和判断多个value
当布隆过滤器说某个值存在时,这个值可能不存在;当它说不存在时,那就肯定不存在。
-
基本使用
// 连接redis操作 conn, err := redis.Dial("tcp", "127.0.0.1:6380") HandlecError(err, "connect") defer func() { _ = conn.Close() }() // 测试redis的布隆过滤器 res, err := conn.Do("bf.add", "reBloom", "user100") fmt.Println(res, err) res2, err2 := conn.Do("bf.exists", "reBloom", "user1") fmt.Println(res2, err2)
-
go测试误判小实验
// 每次生成不同的key testKey := uuid.NewV4().String() // 对已经添加进布隆过滤器的他肯定是能判断出来是存在的(res=1) for i := 1; i < 100000 ; i++ { _, _ = conn.Do("bf.add", testKey, "user" + strconv.Itoa(i)) res, _ = conn.Do("bf.exists", testKey, "user" + strconv.Itoa(i)) if res.(int64) == 0{ fmt.Println(i) break } } // 测试结果: 不会误判 // 对于没添加进布隆过滤器的,他可能会误判为存在(res=1) for i := 1; i < 100000 ; i++ { _, _ = conn.Do("bf.add", testKey, "user" + strconv.Itoa(i)) res, _ = conn.Do("bf.exists", testKey, "user" + strconv.Itoa(i + 1)) if res.(int64) == 1{ fmt.Println(i) break } } // 测试结果: i=310就误判了
布隆过滤器可以自定义参数,需要我们在 add 之前使用 bf.reserve 指令显式创建。如果对应的 key 已经存在,bf.reserve 会报错。bf.reserve 有三个参数: 分别是 key, error_rate 和 initial_size。错误率越低,需要的空间越大。initial_size 参数表示预计放 入的元素数量,当实际数量超出这个数值时,误判率会上升。
- 布隆过滤器的原理
- 布隆过滤器的数据结构里面就是一个大型的位数组和几个不一样的无偏(把元素的 hash值算得比较均匀) hash函数, 对每个key都进行多次的hash
- 向布隆过滤器中添加 key 时,会使用多个 hash 函数对 key 进行 hash 算得一个整数索引值, 然后对位数组长度进行取模运算得到一个位置,每个 hash 函数都会算得一个不同的位置。再把位数组的这几个位置都置为1 就完成了 add 操作。
- 向布隆过滤器询问 key 是否存在时,跟 add 一样,也会把 hash 的几个位置都算出来,看看位数组中这几个位置是否都位 1… 只要有一个位为 0,那么说明布隆过滤器中这个 key不存在。如果都是 1,这并不能说明这个key 就一定存在,只是极有可能存在,因为这 些位被置为 1 可能是因为其它的 key 存在所致。
- 布隆过滤器的应用场景
- 推荐内容的去重
- 爬虫URL去重
- 邮箱系统的垃圾邮件过滤