缓存穿透利器之「布隆过滤器」

BitMap

现代计算机用二进制(bit,位)作为信息的基础单位,1 个字节等于 8 位,例如big字符串是由 3 个字节组成,但实际在计算机存储时将其用二进制表示,big分别对应的 ASCII 码分别是 98、105、103,对应的二进制分别是 01100010、01101001 和 01100111。

许多开发语言都提供了操作位的功能,合理地使用位能够有效地提高内存使用率和开发效率。

Bit-map 的基本思想就是用一个 bit 位来标记某个元素对应的 value,而 key 即是该元素。由于采用了 bit 为单位来存储数据,因此在存储空间方面,可以大大节省。

在 Java 中,int 占 4 字节,1 字节 = 8位(1 byte = 8 bit),如果我们用这个 32 个 bit 位的每一位的值来表示一个数的话是不是就可以表示 32 个数字,也就是说 32 个数字只需要一个 int 所占的空间大小就可以了,那就可以缩小空间 32 倍。

1 Byte = 8 Bit,1 KB = 1024 Byte,1 MB = 1024 KB,1GB = 1024 MB

假设网站有 1 亿用户,每天独立访问的用户有 5 千万,如果每天用集合类型和 BitMap 分别存储活跃用户:

  1. 假如用户 id 是 int 型,4 字节,32 位,则集合类型占据的空间为 50 000 000 * 4/1024/1024 = 200M;
  2. 如果按位存储,5 千万个数就是 5 千万位,占据的空间为 50 000 000/8/1024/1024 = 6M。

那么如何用 BitMap 来表示一个数呢?

上面说了用 bit 位来标记某个元素对应的 value,而 key 即是该元素,我们可以把 BitMap 想象成一个以位为单位的数组,数组的每个单元只能存储 0 和 1(0 表示这个数不存在,1 表示存在),数组的下标在 BitMap 中叫做偏移量。比如我们需要表示{1,3,5,7}这四个数,如下:

image-20220311102113004

那如果还存在一个数 65 呢?只需要开int[N/32+1]个 int 数组就可以存储完这些数据(其中 N 表示这群数据中的最大值),即:

int[0]:可以表示 0~31

int[1]:可以表示 32~63

int[2]:可以表示 64~95

image-20220311102821020

假设我们要判断任意整数是否在列表中,则 M/32 就得到下标,M%32就知道它在此下标的哪个位置,如:

65/32 = 265%32=1,即 65 在int[2] 中的第 1 位。

布隆过滤器

本质上布隆过滤器是一种数据结构,比较巧妙的概率型数据结构,特点是高效地插入和查询,可以用来告诉你 “某 样东西一定不存在或者可能存在”。

相比于传统的 List、Set、Map 等数据结构,它更高效、占用空间更少,但是缺点是其返回的结果是概率性的,而不是确切的。

实际上,布隆过滤器广泛应用于网页黑名单系统垃圾邮件过滤系统爬虫网址判重系统等,Google 著名的分布式数据库 Bigtable 使用了布隆过滤器来查找不存在的行或列,以减少磁盘查找的 IO 次数,Google Chrome 浏览器使用了布隆过滤器加速安全浏览服务。

在很多 Key-Value

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

汪了个王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值