1. 概述
Redis是一个高性能的内存数据结构存储,不仅支持高效的键/值存储,也提供了一些高级数据结构,比如哈希映射,集合等,其中bitmap(位图)也是一个很有趣的数据结构。
在实际应用中,我们经常需要对用户行为活动进行统计,比如统计活跃用户量、统计用户在线时长等等。针对这种类型统计,用传统的关系型数据库或者NoSQL数据库都可以实现,但是操作比较复杂而且效率不高。而使用Redis的bitmap,可以大大简化操作,同时极大提升统计效率。本文主要介绍如何使用Redis的bitmap统计活跃用户。
2. Bitmaps
2.1 什么是Bitmaps
Bitmaps(位图)是一种数据结构,用于存储位状态的集合。比如我们有一组数字{1,2,3,4,5,6,7,8},我们可以将其表示为8位二进制数:
00000001 00000010 00000011 00000100 00000101 00000110 00000111 00001000
其中,每一位表示该数字是否出现过。如果是,就将该位置为1,否则为0。
2.2 Redis的Bitmaps
Redis的Bitmaps是一个非常实用的内置数据结构,它存储的是一个特殊的字符串,字符串中的每个字节(byte)只能是0或1。但是这个字符串非常大,最多可以存储2^32位,即2^32/8个字节,也就是512MB的二进制数据。
Redis提供了一系列对Bitmaps进行操作的命令,比如setbit,getbit,bitcount等等。下面我们看一个简单的例子:
假设我们有一个用户列表,编号分别为1、2、3、4、5、6、7、8,我们现在要统计编号为1、2、3、4、7的用户是否在线,我们假设在线的用户编号是1、3、4、7,我们可以这么表示:
setbit online_user 1 1 # 将第1个用户标记为在线
setbit online_user 2 0 # 将第2个用户标记为下线
setbit online_user 3 1 # 将第3个用户标记为在线
setbit online_user 4 1 # 将第4个用户标记为在线
setbit online_user 5 0 # 将第5个用户标记为下线
setbit online_user 6 0 # 将第6个用户标记为下线
setbit online_user 7 1 # 将第7个用户标记为在线
setbit online_user 8 0 # 将第8个用户标记为下线
然后我们可以使用getbit命令检查该用户是否在线:
getbit online_user 1 # 检查第1个用户是否在线,结果为1
getbit online_user 2 # 检查第2个用户是否在线,结果为0
getbit online_user 3 # 检查第3个用户是否在线,结果为1
getbit online_user 4 # 检查第4个用户是否在线,结果为1
getbit online_user 5 # 检查第5个用户是否在线,结果为0
getbit online_user 6 # 检查第6个用户是否在线,结果为0
getbit online_user 7 # 检查第7个用户是否在线,结果为1
getbit online_user 8 # 检查第8个用户是否在线,结果为0
bitcount命令可以方便地获取在线用户的个数:
bitcount online_user # 获取在线用户个数,结果为3
3. 使用Bitmaps统计活跃用户
下面我们介绍如何使用Redis的Bitmaps统计活跃用户。假设我们有一个网站,我们要从用户访问日志中统计每天的活跃用户量。
3.1 创建Bitmap
我们可以为每一天创建一个Bitmap,用来表示该天是否有用户访问。假设我们现在要创建2022年1月1日的Bitmap,我们可以这么做:
setbit active_user_20220101 1 1
其中,第一个参数是Bitmap的名称,这里以日期为名称;第二个参数是用户编号,我们假设用户编号为1;第三个参数是状态值,表示该用户在该日期当天是否活跃,如果活跃,就将其标记为1,否则为0。
3.2 统计活跃用户
假设1月2日有2个用户访问,编号分别是2、3,我们可以这么统计:
setbit active_user_20220102 2 1
setbit active_user_20220102 3 1
这样,我们就将该日的活跃用户标记出来了。
如果要统计某段时间范围内的活跃用户,只需要将该时间范围内的所有Bitmap进行与运算,最终得到的Bitmap就是该时间范围内活跃用户的情况。比如要统计1月1日到1月3日之间的活跃用户,我们就可以这么做:
bitop and active_user_20220101_03 active_user_20220101 active_user_20220102 active_user_20220103
此时,active_user_20220101_03字符串中,每个字节的每一位对应该用户在该时间范围内是否活跃。我们可以使用bitcount命令方便地获取活跃用户的数量:
bitcount active_user_20220101_03
4. 总结
本文介绍了Redis的Bitmaps数据结构,并且详细讲解了如何使用Bitmaps统计活跃用户。使用Redis的Bitmaps可以大大提高活跃用户统计的效率,同时操作也比较简单,并且可以方便地扩展到多个时间段的统计。