布隆过滤器
检索元素是否存在大集合中
判断不存在的key,一定不存在;判断存在的key,有可能不存在
优点:插入、查询速度快、占用空间小、保密性好(存储的都是0和1)
缺点:很难进行删除操作、误判(误判率可设置)
原理
就是计算数据的哈希值、再由哈希值映射到数组的下标
存入、查询
对你好进行多个哈希计算,计算出对应的下标:比如,3、5、7。
如果是存入,就将对应的下标的值改为1
如果是查询,那3、5、7中只要有一个不是1,那该数据就不在布隆过滤器存在
删除
当你好和hello通过哈希,计算出的下标都是2时,如果想删除你好的数据。就也会把hello的删掉
Java模拟
import com.google.common.hash.BloomFilter;
import com.google.common.hash.Funnels;
/**
* @date 2023/3/5 下午2:54
* 布隆过滤器
*/
public class Test {
/**
* 长度
*/
private static int size = 1000000;
/**
* 误判率
*/
private static double fpp = 0.01;
/**
* 布隆过滤器
*/
private static BloomFilter<Integer> bloomFilter = BloomFilter.create(Funnels.integerFunnel(),size,fpp);
// 测试布隆过滤器误判率
public static void main(String[] args) {
// 先给布隆过滤器放百万条数据
for (int i=0;i<1000000;i++){
bloomFilter.put(i);
}
// 测试误判率
int count = 0;
for (int i= 1000000;i<1000000+100000;i++){
if (bloomFilter.mightContain(i)){
// 误判了
count++;
}
}
System.out.println("总共误判次数:" + count);
}
}
尝试后,误判率还真是:0.01
总结:
误判率越小,占用空间大小更大,需要的哈希函数就越多。所以性能就越差
Redis的布隆过滤器
// redis使用布隆过滤器
public static void main(String[] args) {
Config config = new Config();
// 此处改为连接集群即可
config.useSingleServer().setAddress("redis:/127.0.0.1:6379");
config.useSingleServer().setPassword("123456");
Redissonlient redissonlient = Redisson.create(config);
// 给布隆过滤器起名字
RBloomFilter<String> rBloomFilter = redissonlient.getBloomilter("aaa");
// 大小、误判率
rBloomFilter.tryInit(1000000L,0.03);
rBloomFilter.add("12122");
// 判断下面的是否在布隆过滤器中
System.out.println(rBloomFilter.contains("21312"));
}
布谷鸟过滤器(布隆加强版)
未完待续