redis初级——Bitmaps位图

Bitmaps位图

1.数据结构模型

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

字符串“big”用二进制表示

​ 许多开发语言都提供了操作位的功能,合理地使用位能够有效地提高内存使用率和开发效率。Redis提供了Bitmaps这个“数据结构”可以实现对位的操作。把数据结构加上引号主要因为:
​ (1)Bitmaps本身不是一种数据结构,实际上它就是字符串,但是它可以对字符串的位进行操作。

字符串“big”用二进制表示

​ (2)Bitmaps单独提供了一套命令,所以在Redis中使用Bitmaps和使用字符串的方法不太相同。可以把Bitmaps想象成一个以位为单位的数组,数组的每个单元只能存储0和1,数组的下标在Bitmaps中叫做偏移量。

2.命令

​ 我们使用用户是否访问过网站为例,介绍Bitmaps的各个命令。将访问的用户记做1,没有访问的用户记做0,用偏移量作为用户的id。

(1) 设置值

set key offset value

设置键的第offset个位的值(从0算起),假设现在有20个用户,userid=0,5,11,15,19的用户对网站进行了访问,那么当前Bitmaps初始化结果如图所示。

setbit使用

具体操作内容如下,使用visit:2024-11-28表示在2024年11月28日访问过的用户。

# 代码示例
> setbit visit:2024-11-28 0 1
(integer) 0

> setbit visit:2024-11-28 5 1
(integer) 0

> setbit visit:2024-11-28 11 1
(integer) 0

> setbit visit:2024-11-28 15 1
(integer) 0

> setbit visit:2024-11-28 19 1
(integer) 0

如果此时有一个userid=50的用户访问了网站,那么Bitmaps的结构变成了下图所示,第20位~49位都是0。

userid=50用户访问

(2) 获取值

getbit key offset

获取用户0和用户8是否在2024年11月28日访问过。

> getbit visit:2024-11-28 0
(integer) 1

> getbit visit:2024-11-28 8
(integer) 0

(3) 获取Bitmaps指定范围内为1的个数

bitcount key [start end]

下面操作计算2024年11月28日这一天访问过的用户总数

> bitcount visit:2024-11-28
(integer) 5

start和end分别表示起始字节和结束字节,起始字节索引也是从0开始。

例如: bitcount visit:2024-11-28 1 3 表示计算位索引下标范围[8,31]之间为1的个数。

> bitcount visit:2024-11-28 1 3
(integer) 3

(4) Bitmaps间的运算

bitop AND | OR | XOR | NOT destkey key [key ...]

bitop是一个复合操作,他可以做多个Bitmaps的and(交集)、or(并集)、not(非)、xor(异或)操作并将结果保存在deskkey中。

假设:

​ 2024年11月28日访问的userid = 0,5,11,15,19

​ 2024年11月29日访问的userid = 1,2,5,9

下面计算两天都访问过的用户数量。

> bitop and visit:and:2024-11-28and2024-11-29 visit:2024-11-28 visit:2024-11-29
(integer) 3

> bitcount visit:and:2024-11-28and2024-11-29
(integer) 1

下面计算2024年1月28日和2024年11月29日任意一天都访问过的用户数量。

> bitop or visit:or:2024-11-28or2024-11-29 visit:2024-11-28 visit:2024-11-29
(integer) 3

> bitcount visit:or:2024-11-28or2024-11-29
(integer) 8

(5)计算Bitmaps中第一个值为targetBit的偏移量

bitpos key targetBit [start end]

​ 下面操作获取2024-11-28当天访问的最小用户id

> bitpos visit:2024-11-28 1
(integer) 0

​ 除此之外我们还可以使用start和end两个参数,分别代表起始字节和结束字节。

> bitpos visit:2024-11-28 1 1 3
(integer) 11

> bitpos visit:2024-11-28 1 2 3
(integer) 19

3.Bitmaps分析

​ 假设有一个网站有1亿用户,每天独立访问的用户有5千万,如果使用集合类型和Bitmaps类型分别存储活跃用户的话可以得到下表。

数据类型每个用户id占用空间需要存储的用户量全部内存量
集合类型64位5千万64位 * 5千万 = 400MB
Bitmaps1位1亿1位 * 1亿 = 12.5MB

​ 很明显,在这种情况下使用Bitmaps可以节省下很多空间。这还是存储一天数据的情况下。随着时间的推移,差距会越来越明显。

数据类型一天一个月一年
set400M12G144G
Bitmaps12.5M375M4.5G

​ 但是并不是什么情况下Bitmaps都比集合表现的好,如果每天独立访问的用户很少只有10万,那么两种数据类型的对比将如下表所示。

数据类型每个用户id占用空间需要存储的用户量全部内存量
集合类型64位10万64位 * 10万 = 800KB
Bitmaps1位1亿1位 * 1亿 = 12.5MB

​ 所以我们要根据不同的情况选择最适合的数据类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值