问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Redis位图(Bitmap)功能详解:常用命令与应用场景

创作时间:
作者:
@小白创作中心

Redis位图(Bitmap)功能详解:常用命令与应用场景

引用
CSDN
1.
https://blog.csdn.net/qq_31753559/article/details/143341824

Redis中的位图(bitmap)功能以其计算效率高和占用空间少的特点,在统计用户登录、签到等场景中得到广泛应用。本文将详细介绍Redis位图的常用命令及其应用场景,帮助读者深入理解这一功能的使用方法。

描述

位图是Redis封装的用于针对位(bit)的操作,其特点是计算效率高,占用空间少,常被用来统计用户签到、登录等场景。

常用命令及解析

常用命令

  • setbit key offset value
    给key在指定位索引位置上(offset)设置一个value,因为是bit所以value只能为0或1;如setbit zhangsan 2 1表示在位索引的2号位设置为1,对应的二进制位应该是0010 0000

  • getbit key offset
    获取key在指定位索引位置上对应的二进制值,要么是0要么是1

  • bitcount key [start end]
    统计key在给定的字节索引范围内1出现的次数;如bitcount zhangsan 1 2表示统计张三在字节所以1-2之间1出现的次数

  • bitpos key bit [start] [end]
    统计key对应的二进制串中指定的bit(1或0)在指定字节索引下标内第一次出现的位置,没有出现返回-1

  • bitop operation destkey key [key …]
    将两个或多个key的二进制位进行或、与的操作然后赋值给指定的新key(destkey);如bitop and k3 k1 k2表示将k1和k2按与操作后赋值给k3

解析

针对上面的常用命令,如果是初识的话有可能会比较蒙蔽,下面结合我画的图来进行解析;首先需要明确的一点是上文提到的offset(偏移量)指的是bit(位)的索引位置,一个字节等于8个bit,bit的索引下标从0开始;然后命令里的start end这些表示的是字节索引位置,如[0,2]表示字节的0到2的区间,相当于3个字节对应bit位置的0-24,下面上图:

针对上图我们再跑一遍上面的常用命令进行解析:

  • setbit zhangsan 3 1 表示将bit下标为3的位置设置为1,二进制表示如下:0001 0000
  • getbit zhangsan 3 表示获取bit下标为3位置上的二进制值为1,如果getbit zhangsan 2则值为0
  • bitcount zhangsan 0 1 表示获取字节下标0-1(相当于bit下标的0-15)之间位置内1出现的次数,这里结果为1
  • bitpos zhangsan 1 0 1 表示获取字节下标0-1(相当于bit下标的0-15)之间位置内1第一次出现的次数,因为上面设置了zhangsan对应的二进制为0001 0000,所以这里结果应为3
  • bitop operation destkey key [key …] 这是bitop前再设置一个key,setbit lisi 2 1,然后执行bitop or k3 zhangsan lisi,这时k3的值因为zhangsan/lisi二进制or运算后的值,应为0011 0000

应用场景

统计不确定时间周期内用户登录情况

比方说需要统计20220101-20220107区间内用户登录的次数

思路分析

针对用户量不是那么多且登录不频繁的非互联网型的应用,利用mysql维护一张用户登录的日志表就能解决问题,但是假设用户量过大且用户登录次数频繁的情况下,mysql就并不是最优解了;这时可以结合使用bitmap来实现这一需求

实现

在redis里维护一个key为用户id的bitmap,用户每次登录时setbit userId offset 1;需要注意的是这里的offset需要进行计算映射,将bit的下标与一年的365天对应上;统计的时候根据不同需求有好几种实现;

  1. bitcount userId 0 -1 统计用户一年登录的次数
  2. 根据具体查询区间循环getbit userId offset;如查询20220101-20220107区间内用户登录的次数则先找到20220101-10对应的偏移量接着循环getbit,判断结果,如果是1则给登录天数加1即可

统计某一特定时间内活跃用户(登录一次即算活跃)的数量

思路分析与实现

将日期作为key,offset映射成不同的用户id,当不同的用户登录时setbit 20210101 offset,如:

setbit 20220101 0 1
setbit 20220102 1 1
setbit 20220102 0 1
setbit 20220102 2 1

以日期为key,将用户id与位索引提前做好映射,比方说0位表示张三1位表示李四2位表示王五,当张三登录时在0位设置1,李四登录在1位设置1,王五登录在2位设置1,统计指定时间时将指定时间对应的key做bitop操作即可,如下:bitop or k3 20220101 20220102 上面命令表示将20220101和02这两个key做or操作,因为二进制or操作是有1即是1,最后统计k3里1出现的次数即得出20210101到02之间活跃用户数为3:bitcount k3 0 -1

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号