redis学习笔记之布隆过滤器

什么是布隆过滤器?

在redis4.0提供了布隆过滤器,简单的来说布隆过滤器就是一个不怎么精确的set结构,当你使用他的contains去判断某个对象是否存在。当布隆器说某个值存在的时候,这个值可能不存在,当他说某个值不存在的时候一定不存在。

布隆过滤器的简单使用

127.0.0.1:6379> bf.add calvinBloom 1
(integer) 1
127.0.0.1:6379> bf.add calvinBloom 2
(integer) 1
127.0.0.1:6379> bf.exists calvinBloom 1
(integer) 1
127.0.0.1:6379> bf.exists calvinBloom 2
(integer) 1
127.0.0.1:6379> bf.exists calvinBloom 3
(integer) 0
#本代码来自redis深度历险
import redis
import random
 
client = redis.StrictRedis()
 
chars = ''.join([chr(ord('a') + i) for i in range(26)])
 
def random_string(n):
    chars_list = []
    for i in range(n):
        ids = random.randint(0, len(chars) - 1)
        chars_list.append(chars[ids])
    return ''.join(chars_list)
 
users = list(set([random_string(64) for i in range(10000)]))
print("total users", len(users))
 
users_train = users[:int(len(users)/ 2)]
users_test = users[int(len(users) / 2):]
 
client.delete("codehole")
falses = 0
for user in users_train:
 
    client.execute_command("bf.add", "codehole", user)
print("all train")
for user in users_test:
    ret = client.execute_command("bf.add", "codehole", user)
    if ret == 1:
        falses += 1
 
print(falses, len(users_test))

从上面的运行的结果看,误判率快接近2%,所以这个误判率还是有点高的。redis中提供了自定参数的布隆过滤器,在bf.add命令前使用bf.reserve创建。bf.reserve有三个参数:key(键),error_rate(错误率),inital_size(预计放入的元素数量)。

注意:

  1. 如果对应的键已经存在则会报错。
  2. inital_size如果设置过大会浪费空间,过小则会影响准确率。使用前尽可能估计元素数量,加上一定量的冗余空间来避免实际元素可能高出估计值太多。

布隆过滤器原理

每个布隆过滤器对应到redis数据结构就是一个大型的位数组和几个不一样的hash函数(h1,h2,h3)。当添加的时候,使用多个hash函数对键进行hash,得到一个哈希值,然后对数组的长度进行求余((length-1)& 哈希值)整数s得到一个位置,并将对应的位置设为1。当向布隆过滤器查询键时,和add一样,找到相应的位置,看看是否为1,只要有一个是0,就说明键不存在,反之存在。 

空间占用估计 


n:预计元素的数量    f:错误率    m:位数组长度    k:哈希函数的最佳数量

k = 0.7*(m/n)

f = 0.6185^(m/n)

从以上公式可以得出:位数组相对越长,错误率越低,hash函数需要的最佳数量也越多(影响判断效率)

这里我直接把redis深度历险书中结论拿出来,推导看下面推荐

推荐阅读

布隆过滤器及其数学推导

布隆过滤器计算器(结合上面这个推荐理解使用)

常见面试题之布隆过滤器的使用案例(海量数据)

猜你喜欢

转载自blog.csdn.net/lin_keys/article/details/105959545
今日推荐