欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

redis位图法bitmap统计活跃用户

程序员文章站 2022-07-05 20:40:33
...

位图法

位图(bitmap),就是用位(bit)来表示存放的某种状态,如开关,有无。在redis中,字符串是以二进制的形式存储的,因此位图在redis中并不是一种数据类型,而是一种字符串的表现形式。位图中每个元素在内存中占用1位,所以可以节省存储空间。

 

相关命令

1、SETBIT key offset value

该命令时间复杂度: O(1),效率极高;

对 key 所储存的字符串值,设置或清除指定偏移量上的位(bit)。

位的设置或清除取决于 value 参数,可以是 0 也可以是 1 。

当 key 不存在时,自动生成一个新的字符串值。

字符串会进行伸展以确保它可以将 value 保存在指定的偏移量上。当字符串值进行伸展时,空白位置以 0 填充。

offset 参数必须大于或等于 0 ,小于 2^32 (bit 映射被限制在 512 MB 之内)。

 

2、BITOP operation destkey key [key …]

该命令时间复杂度: O(N)

对一个或多个保存二进制位的字符串 key 进行位元操作,并将结果保存到 destkey 上。

operation 可以是 AND 、 OR 、 NOT 、 XOR 这四种操作中的任意一种:

  • BITOP AND destkey key [key ...] ,对一个或多个 key 求逻辑并,并将结果保存到 destkey 。

  • BITOP OR destkey key [key ...] ,对一个或多个 key 求逻辑或,并将结果保存到 destkey 。

  • BITOP XOR destkey key [key ...] ,对一个或多个 key 求逻辑异或,并将结果保存到 destkey 。

  • BITOP NOT destkey key ,对给定 key 求逻辑非,并将结果保存到 destkey 。

除了 NOT 操作之外,其他操作都可以接受一个或多个 key 作为输入。

 

3、BITCOUNT key [start] [end]

该命令时间复杂度: O(N)

计算给定字符串中,被设置为 1 的比特位的数量。

一般情况下,给定的整个字符串都会被进行计数,通过指定额外的 start 或 end 参数,可以让计数只在特定的位上进行。

start 和 end 参数的设置和 GETRANGE key start end 命令类似,都可以使用负数值: 比如 -1 表示最后一个字节, -2 表示倒数第二个字节,以此类推。

不存在的 key 被当成是空字符串来处理,因此对一个不存在的 key 进行 BITCOUNT 操作,结果为 0 。

 

统计活跃用户

为了统计每日登录的用户数,建立了一个bitmap, 每一位标识一个用户ID。

redis位图法bitmap统计活跃用户

当某个用户登录了网站或执行了某个操作,就在bitmap中把标识此用户的位置为1,未登录默认为0,

然后进行and操作,即可统计活跃用户数。

redis key可以设计成:时间周;

offset 用user_id。

用户登录数据如下:

100 、101、102、103 代表用户user_id

周一:{100,101,102,103}

周二:{101,102,103}

周三:{101,102}

周四:{100,101,102}

周五:{100,101,102,103}

周六:{101,102,103}

周日:{100,101,102}

一周内连续登录的用户有2个:{101,102}

 

以下使用命令演示一周的用户登录情况:

localhost:6379:0>SETBIT mon 100 1
0

localhost:6379:0>SETBIT mon 101 1
0

localhost:6379:0>SETBIT mon 102 1
0

localhost:6379:0>SETBIT mon 103 1
0

localhost:6379:0>SETBIT tue 101 1
0

localhost:6379:0>SETBIT tue 102 1
0

localhost:6379:0>SETBIT tue 103 1
0

localhost:6379:0>SETBIT wed 101 1
0

localhost:6379:0>SETBIT wed 102 1
0

localhost:6379:0>SETBIT thu 100 1
0

localhost:6379:0>SETBIT thu 101 1
0

localhost:6379:0>SETBIT thu 102 1
0

localhost:6379:0>SETBIT fri 100 1
0

localhost:6379:0>SETBIT fri 101 1
0

localhost:6379:0>SETBIT fri 102 1
0

localhost:6379:0>SETBIT fri 103 1
0

localhost:6379:0>SETBIT sat 101 1
0

localhost:6379:0>SETBIT sat 102 1
0

localhost:6379:0>SETBIT sat 103 1
0

localhost:6379:0>SETBIT sun 100 1
0

localhost:6379:0>SETBIT sun 101 1
0

localhost:6379:0>SETBIT sun 102 1
0

统计一周内连续登录用户:

localhost:6379:0>BITOP AND result mon tue wed thu fri sat sun
13

localhost:6379:0>BITCOUNT result
2

 

使用 bitmap 实现用户上线次数统计

假设现在我们希望记录自己网站上的用户的上线频率,比如说,计算用户 A 上线了多少天,用户 B 上线了多少天,诸如此类,以此作为数据,从而决定让哪些用户参加 beta 测试等活动 —— 这个模式可以使用 SETBIT key offset value 和 BITCOUNT key [start] [end] 来实现。

比如说,每当用户在某一天上线的时候,我们就使用 SETBIT key offset value ,以用户名作为 key ,将那天所代表的网站的上线日作为 offset 参数,并将这个 offset 上的value设置为 1 。

举个例子,如果今天是网站上线的第 100 天,而用户 peter 在今天阅览过网站,那么执行命令 SETBIT peter 100 1 ;如果明天 peter 也继续阅览网站,那么执行命令 SETBIT peter 101 1 ,以此类推。

当要计算 peter 总共以来的上线次数时,就使用 BITCOUNT key [start] [end] 命令:执行 BITCOUNT peter ,得出的结果就是 peter 上线的总天数。

 

参考资料:http://redisdoc.com/bitmap/index.html