LevelDB 学习笔记1:布隆过滤器

  • 底层是位数组,初始都是 0
  • 插入时,用 k 个哈希函数对插入的数字做哈希,并用位数组长度取余,将对应位置 1
  • 查找时,做同样的哈希操作,查看这些位的值
    • 如果所有位都是 1,说明数字可能存在
    • 如果有某个位不是 1,说明数字一定不存在

数学结论

影响布隆过滤器精度的参数有

  • 哈希函数的个数 k
  • 布隆过滤器位数组的容量 m
  • 布隆过滤器插入的数据数量 n

对于给定的 m 和 n,要想最小化错误率(假阳性),k 应该取

\[k=\frac{m}{n} \ln 2 \]

要求错误率不大于\(\varepsilon\),k 取最优的情况下,m 应该至少为

\[m \geq - 1.44 \log _{2} \varepsilon * n \]

布隆过滤器的优缺点

优点

  • 空间效率高,可以在使用有限内存的情况下处理海量数据

    • 1% 错误率并使用最佳 k 值的布隆过滤器,每个元素只需要使用约 9.6 位
  • 插入和查询都是常数复杂度,即 O(k)

缺点

  • 存在误判
  • 删除元素困难,因为简单地将对应的位置 0 会影响其他元素的判断
    • 可以用一种叫 Counting Bloom filter 的变体

LevelDB 中的布隆过滤器

LevelDB 中利用布隆过滤器判断指定的 key 值是否存在于 sstable 中

  • 若过滤器认为 key 不在 sstable 中,那么就没必要查找这个 sstable 了
  • 否则,key 有可能在 sstable 中,应该做查找

使用布隆过滤器可以有效的减少调用 DB::Get() 时的访存次数,从而减小读放大

LevelDB 中布隆过滤器的实现是 BloomFilterPolicy,它是接口类 FilterPolicy 的实现

  • FilterPolicy 类决定了查找过程中要不要读取某个 sstable
  • 允许用户自定义 FilterPolicy 的子类来应用不同的过滤策略

LevelDB 实现时做了优化,它并不是使用 k 个哈希函数,而是应用 rsa2008 中提出的方法只生成一次哈希值,然后用 double-hashing 的方式生成一组哈希值

uint32_t h = BloomHash(keys[i]);
const uint32_t delta = (h >> 17) | (h << 15); // Rotate right 17 bits
for (size_t j = 0; j < k_; j++) {
const uint32_t bitpos = h % bits;
array[bitpos / 8] |= (1 << (bitpos % 8));
h += delta;
}

一般实现布隆过滤器时,都会选择非加密哈希算法

  • 加密哈希算法,比如 MD5、SHA1,安全性较高,难以找到碰撞或通过加密值反推原文
  • 非加密哈希算法,比如 MurMurHash、CRC32、FNV,计算速度快
  • LevelDB 实现了一个类似于 MurMurHash 的非加密哈希算法

其他应用场景

缓存穿透

做查询的时候,缓存没有命中,就会到数据库中去找,特别地,如果查找一个不存在的 key,那么是一定无法命中缓存,必须去查数据库的,如果有人恶意地使用大量请求来查不存在的 key,就会导致数据库压力过大,甚至崩溃,这种现象称为缓存穿透

用布隆过滤器我们可以直接将这些针对不存在的 key 发起的请求过滤掉

LevelDB 学习笔记1:布隆过滤器的更多相关文章

  1. LevelDB学习笔记 (1):初识LevelDB

    LevelDB学习笔记 (1):初识LevelDB 1. 写在前面 1.1 什么是levelDB LevelDB就是一个由Google开源的高效的单机Key/Value存储系统,该存储系统提供了Key ...

  2. LevelDB学习笔记 (3): 长文解析memtable、跳表和内存池Arena

    LevelDB学习笔记 (3): 长文解析memtable.跳表和内存池Arena 1. MemTable的基本信息 我们前面说过leveldb的所有数据都会先写入memtable中,在leveldb ...

  3. LevelDB 学习笔记2:合并

    LevelDB 学习笔记2:合并 部分图片来自 RocksDB 文档 Minor Compaction 将内存数据库刷到硬盘的过程称为 minor compaction 产出的 L0 层的 sstab ...

  4. leveldb 学习笔记之VarInt

    在leveldb在查找比较时的key里面保存key长度用的是VarInt,何为VarInt呢,就是变长的整数,每7bit代表一个数,第8bit代表是否还有下一个字节, 1. 比如小于128(一个字节以 ...

  5. angular学习笔记(十六) -- 过滤器(2)

    本篇主要介绍angular自定义的过滤器: 直接看例子: <!DOCTYPE html> <html ng-app="MyFilter"> <head ...

  6. angular学习笔记(十六) -- 过滤器(1)

    本篇主要介绍过滤器的基本用法: 过滤器用来对数据进行格式的转换,数据格式的转化与逻辑无关,因此,我们使用过滤器来进行这些操作: {{... | filter2: 参数1,参数2... }} expre ...

  7. Qt5学习笔记(消息过滤器)

    T06EventFilter.pro HEADERS += \ MyWidget.h SOURCES += \ MyWidget.cpp QT += widgets gui MyWidget.h #i ...

  8. leveldb学习笔记

    LevelDB由 Jeff Dean和Sanjay Ghemawat开发. LevelDb是能够处理十亿级别规模Key-Value型数据持久性存储的C++ 程序库. 特别如下: 1.LevelDb是一 ...

  9. Vue学习笔记十:过滤器

    目录 公共过滤器的写法 简易过滤器+带参数过滤器+多过滤器 私有过滤器 公共过滤器的写法 过滤器的写法还是很简单的 ,如下 <p>{{ msg | filtermsg }}</p&g ...

随机推荐

  1. CF回顾《二分类》

    cf Educational Codeforces Round 115 (Rated for Div. 2) C题 类型:二分查找. 中文题目: C.删除两项内容 Monocarp有一个由n个整数组成 ...

  2. K8S原来如此简单(三)Pod+Deployment

    上篇我们已经安装好k8s1.23集群,现在我们开始使用k8s部署我们的项目 Pod Pod 是一组容器集合,是可以在 Kubernetes 中创建和管理的.最小的可部署的计算单元.这些容器共享存储.网 ...

  3. 域环境SID相同如何解决

    查看SID 进入命令行(WIN+R) 输入     whoami /user 什么是SID? sid相当于系统的身份证号,在域内有相同sid的计算机就相当于两个人共同有一个身份证号码,后果可想而知 建 ...

  4. 6月4日 python学习总结 初次接触jQuery

    1. jQuery是什么?是一个轻量级的,兼容多浏览器的JS库(write less, do more) 1. 是一个工具,简单方便的实现一些DOM操作 2. 不用jQuery完全可以,但是不明智. ...

  5. 3、Lambda表达式

    Lambda表达式 Lambda表达式(lambda expression),是一种匿名函数,即没有函数名的函数. Lambda表达式不仅在C#中使用,在Java.Phtyon.C++ 中都有使用. ...

  6. 什么是 FreeMarker 模板?

    FreeMarker 是一个基于 Java 的模板引擎,最初专注于使用 MVC 软件架构进行动态网页生成.使用 Freemarker 的主要优点是表示层和业务层的完全分离.程序员可以处理应用程序代码, ...

  7. 在 Spring中如何注入一个java集合?

    Spring提供以下几种集合的配置元素: 类型用于注入一列值,允许有相同的值. 类型用于注入一组值,不允许有相同的值. 类型用于注入一组键值对,键和值都可以为任意类型. 类型用于注入一组键值对,键和值 ...

  8. 表单属性method的值get和post的区别?什么时候用get?什么时候用post?

    get和post的区别 一.安全性 因为get会将用户名和密码放在URL中,进而出现在浏览器的历史记录中,显然这种情况应该用post. 二.编码 get只能向服务器发送ASCII字符,而post则可以 ...

  9. Spring Framework 有哪些不同的功能?

    轻量级 - Spring 在代码量和透明度方面都很轻便.IOC - 控制反转 AOP - 面向 切面编程可以将应用业务逻辑和系统服务分离,以实现高内聚.容器 - Spring 负 责创建和管理对象(B ...

  10. Vue报错之" [Vue warn]: Unknown custom element: <wzwzihello> - did you register the component correctly? For recursive components, make sure to provide the "name" option."

    一.报错截图 [Vue warn]: Unknown custom element: <wzwzihello> - did you register the component corre ...