redis学习四-位图(bitmap)使用

1 bitmap简介

现代计算机都是用二进制(位)作为信息的基础,1个字节=8位,如big有2个字符组成,对应的ASCII值分别是98、105、103、对应的二进制分别是01100010、01101001、01100111,如下图
        b              i              g
01100010 01101001 01100111
bitmap本身并不是数据结构,实际上就是字符串,但是它可以对字符串的位进行操作,可以把bitmap想象成一个以bit为单位的数组,数组每个单元只存储0、1,数组的下标叫bitmap的偏移量
bitmap最大支持2^32位,字符串最大512M,每个字节8位,所以bitmap最大支持长度为:8 * 1021 * 1024 * 512,约42亿

2 常用命令

下面以用户登录在某天登录来介绍

2.1 设置值

setbit key offset value
假如有20个用户,0、5、11、15、19在当天对网站进行了访问,执行如下命令
127.0.0.1:6379> setbit user:login:2020-08-30 0 1
(integer) 0
127.0.0.1:6379> setbit user:login:2020-08-30 5 1
(integer) 0
127.0.0.1:6379> setbit user:login:2020-08-30 11 1
(integer) 0
127.0.0.1:6379> setbit user:login:2020-08-30 15 1
(integer) 0
127.0.0.1:6379> setbit user:login:2020-08-30 19 1
(integer) 0

2.2 获取值

2.2.1 获取某个位上的值

getbit key offset
获取0号用户和8号用户在2020-08-30这天是否访问过
127.0.0.1:6379> getbit user:login:2020-08-30 0
(integer) 1
127.0.0.1:6379> getbit user:login:2020-08-30 8
(integer) 0

2.2.2 获取指定范围内个数为1的值

bitcount key [start end]
    start:位的开始字节
    end:位的截止字节
统计2020-08-30这天所有登录人数
127.0.0.1:6379> bitcount user:login:2020-08-30
(integer) 5
查询前前16名用户在2020-08-30这天登录人数
127.0.0.1:6379> bitcount user:login:2020-08-30 0 1
(integer) 4

2.3 bitmap间运算

假如1、2、5、15四个用户在2020-08-31这天进行访问
127.0.0.1:6379> setbit user:login:2020-08-31 1 1
(integer) 0
127.0.0.1:6379> setbit user:login:2020-08-31 2 1
(integer) 0
127.0.0.1:6379> setbit user:login:2020-08-31 5 1
(integer) 0
127.0.0.1:6379> setbit user:login:2020-08-31 15 1
bitmap间预算:bitop operation destkey key [key ...]
    operation:操作名称,and(交集)、or(并集)、not(非)、xor(异或),并将结果保存在中
    destkey:操作结果存储在destkey中
与运算:计算这两天都访问过网站的用户数
    127.0.0.1:6379> bitop and user:login:2020-08-30and2020-08-31 user:login:2020-08-30 user:login:2020-08-31
    (integer) 3
    127.0.0.1:6379> bitcount user:login:2020-08-30and2020-08-31
    (integer) 2
或运算:计算两天访问过网站的用户总数
    127.0.0.1:6379> bitop or user:login:2020-08-30or2020-08-31 user:login:2020-08-30 user:login:2020-08-31
    (integer) 3
    127.0.0.1:6379> bitcount user:login:2020-08-30or2020-08-31
    (integer) 7

2.4 计算bitmap中第一个值是targetBit的偏移量

bitpos key bit [start] [end]
    key:键
    bit:目标bit值
    start:位的开始字节
    end:位的截止字节
查看2020-08-30这天访问网站的最小用户id
    127.0.0.1:6379> bitpos user:login:2020-08-30 1
    (integer) 0

3 bitmap节省空间量

假设网站有1亿用户,每天访问用户量5000w,如果每天用集合类型和bitmap来存储访问用户可以得到如下统计
数据类型        每个用户id占用空间        需要存储用户量        全部内存量
集合类型        64位                        5000w                64bit * 50000000 = 400MB
bitmap         1位                        1亿                    1bit * 100000000 = 12.5MB
可以看到bitmap来统计可以节省大量内存

4 最佳实践

4.1 很多应用用户id以一个指定的数字开头,直接用id作为偏移量会造成一定的浪费,通常做法是将用户id减去一个数值来作为偏移量。第一次初始化bitmap的时候,如果偏移量太大,那么初始化过程会比较慢,造成redis阻塞
4.2 如果统计数据过少,就没有必要用bitmap来存储了,同样1亿用户量,bitmap固定占用12.5MB内存,但是集合内存占用和用户量成正比
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值