文章目录
- 简介
- 操作
- 增
- 访问网站
- 查
- 对比
简介
- 现在计算机用二进制(位)作为信息的基础单位,1个字节等于8位
- 例如
abc
字符串是有3个字节组成,但实际在计算机存储时将其用二进制表示 -
abc
分别对应ASCII码分别是 97、98、99,对应的二进制分别是01100001/01100010/01100011,如下图
2. 合理的使用操作位能够有效的提高内存的使用率和开发效率
3. redis提供了Bitmaps这个数据类型,可以实现对于为的操作
1. Bitmaps本身不是一种数据类型,实际上他就是字符串(key-value),但是他可以对于字符串的位进行操作
2. Bitmaps单独提供了一套命令,所以在redis中使用Bitmaps和使用字符串的方法不太相同。可以把Bitmaps想象成一个以位为单位的数组,数组的每个单位只能存储0,1,数组的下标在Bitmaps中叫做偏移量,如下图
操作
增
setbit<key><offset><value>
设置Bitmaps中某个偏移量的值(0或1),其中offset
是从0开始的
- 在第一次设置
Bitmaps
的时候,如果偏移量比较大,俺么整个初始化的活成会比较慢,就会造成redis的阻塞
访问网站
假设这个时候有20个用户,记录这20用于是否访问了网站,我们可能会做如下操作
- 其中userid从0开始,userid为 1,6,11,15,19的用户对于网站进行了访问,那么他最终的结果应该是如下
- 我们会做如下的操作
- 其中,键
unique:users:20221022
表示2022-10-22这一天对立访问用的用户 - 下标对应着userid
注意
- 很多应用的用户的id,以一个指定的数字开头(如10000),直接将用户id和Bitmaps的偏移量对应势必会造成一定的浪费,通常的做法是每次做setbit操作是将用户的id减去这个指定的数字
查
-
getbit<key><offset>
:查询Bitmaps中某个偏移量的值
接着增加的例子,我们可以看看2022-10-22这天id为9的用户是否访问了网站
他返回的是0,说明他并没有访问
-
bitcount key [start end]
:统计从start位置到end位置的比特值为1的数量
-
bitop and(or/not/xor) <destkey> [key…]
:他是一个复合操作,可以用作多个Bitmaps的and(交集)/or(并集)/not(非)/xor(异或),并将操作结果存到destkey中
对比
Bitmap与set对比
- 假设网站有1亿用户, 每天独立访问的用户有5千万, 如果每天用集合类型和Bitmaps分别存储活跃用户可以得到表
set和Bitmaps存储一天活跃用户对比
数据类型 | 每个用户id占用空间 | 需要存储的用户量 | 全内存量 |
集合类型 | 64位 | 50000000 | 64位*50000000 = 400MB |
Bitmaps | 1位 | 100000000 | 1位*100000000 = 12.5MB |
很明显, 这种情况下使用Bitmaps能节省很多的内存空间, 尤其是随着时间推移节省的内存还是非常可观的
数据类型 | 一天 | 一个月 | 一年 |
集合类型 | 400MB | 12GB | 144GB |
Bitmaps | 12.5MB | 375MB | 4.5GB |
但Bitmaps并不是万金油, 假如该网站每天的独立访问用户很少, 例如只有10万(大量的僵尸用户) , 那么两者的对比如下表所示, 很显然, 这时候使用Bitmaps就不太合适了, 因为基本上大部分位都是0。
set和Bitmaps存储一天活跃用户对比(独立用户比较少)
数据类型 | 每个userid占用空间 | 需要存储的用户量 | 全部内存量 |
集合类型 | 64位 | 100000 | 64位*100000 = 800KB |
Bitmaps | 1位 | 100000000 | 1位*100000000 = 12.5MB |