0

0

使用Redis的bitmaps统计活跃用户

齐天大圣

齐天大圣

发布时间:2020-05-20 07:19:21

|

2414人浏览过

|

来源于php中文网

原创

首先我们看一个场景:一个网站,需要统计一周内连续登陆的用户,以及一个月内登陆过的用户。

如果用传统的数据库如Mysql来实现的话,很难做到。但如果用Redis来做的话,就很简便。Redis的集合类型和Bitmap类型都可以很容易的做到。今天,我们主要来谈谈如何用Bitmaps来实现统计活跃用户的功能。

Bitmaps

在计算机系统中,最小的信息单位是字节,1个字节等于8位,每一位都只可能是0或1(计算机只认识这两个数)。使用Bitmaps可以直接对位进行操作。

可以把bigmaps看做一个数组,数组里每一位只可能是0或者1,数组的下标在这里看做偏移量。

下面我们来介绍几个和Bitmaps相关的命令:

setbit

setbit key offset value:给对应的位设置值

比如今天有用户3、8、23、32访问了网站,则

setbit user:view:2020-5-17 3 1
setbit user:view:2020-5-17 8 1
setbit user:view:2020-5-17 23 1
setbit user:view:2020-5-17 32 1

开发提示:很多应用id都不是从1开始,有许多是从指定数字开始的,比如1001、10001开始。对于这些,我们在设置的时候可以先减去初始值,防止浪费空间

getbit

getbit key offset 获取指定位的值

如果我想知道今天8号用户和45号用户是否登录过,则

127.0.0.1:6379> getbit user:view:2020-5-17 8
(integer) 1
127.0.0.1:6379> getbit user:view:2020-5-17 45
(integer) 0

可以看到8号用户今天登录过,但是45号用户今天还没有登录。

bitcount

bitcount key [start] [end] 获取指定范围为1的个数

我想知道今天有多少用户登陆过了,则

127.0.0.1:6379> bitcount user:view:2020-5-17
(integer) 4

Bitmaps间的操作

bitop op destkey key [key ...]

麦当秀MindShow AiPPT
麦当秀MindShow AiPPT

麦当秀|MINDSHOW是一款百万用户正在使用的三分钟生成一份PPT的AI应用系统。它利用引领前沿的人工智能技术,能够自动完成演示内容的设计。

下载

bitop命令可以对多个bitmaps做交集(and)、并集(or)、非(not)、异或(xor),并将操作结果存放在destkey中。

如果想知道连续三天都登陆过的用户,即5月17日、18日、19日都登陆的用户数量。

这三天登陆情况如下:

  • 5月17日3、8、23、32用户登陆过

  • 5月18日3、23、43、54号用户登陆过

  • 5月19日3、5、23、 32、56、78号用户登陆过

127.0.0.1:6379> bitop and three:and user:view:2020-5-17 user:view:2020-5-18 user:view:2020-5-19
127.0.0.1:6379> bitcount three:and
(integer) 2

如果想知道,这三天有多少用户登陆过。

127.0.0.1:6379> bitop or three:or user:view:2020-5-17 user:view:2020-5-18 user:view:2020-5-19
(integer) 10
127.0.0.1:6379> bitcount three:or
(integer) 9

可以看到,这三天共有9位用户登陆过。

实战

讲完上面所讲知识后,我们就可以来完成想要的需求:需要统计一周内连续登陆的用户,以及一个月内登陆过的用户。

首先模拟用户30天内登陆情况,伪代码如下:

for ($i = 0; $i < 20000; $i++) {
    $userId = mt_rand(1, 10000);
    $date   = time() - 86400 * mt_rand(0, 30);
    $key   = 'userlogin_'.date('Ymd', $date);
 
    $redis->setBit($key, $userId, 1);
}

获取一周内都登陆的用户,当然我们不会一次性全部取,而是想分页那样,一次取一定数量的,伪代码如下:

for ($i = 1; $i <= 7; $i ++) {
    $key = "userlogin_".date('Ymd', time() - (86400*$i));
 
    if ($i == 1) {
        $redis->bitOp('and', 'week_logined', $key);
    } else {
        $redis->bitOp('and', 'week_logined', 'week_logined', $key);
    }
}
 
// 获取前50个用户
$userIds = [];
for ($i=1; $i<=10000; $i++) {
    $ret = $redis->getBit('week_logined', $i);
    $ret && $userIds[] = $i;
 
    if (count($userIds) >=50) break;
}

这里面有一个注意点,也是易错点,在bitop时候,第一次的时候,因为week_logined还不存在,所以进行op的键只有一个。当从第二次开始时候,进行op的键就为2个了。

获取一个月内登陆的用户,思路基本和上面一样,只是将and改为or

for ($i = 1; $i <= 3; $i ++) {
    $key = "userlogin_".date('Ymd', time() - (86400*$i));
    $redis->bitOp('or', 'month_loginOnce', 'month_loginOnce', $key);
}
 
// 获取一个月内登陆过的用户
$userIds = [];
for ($i=1; $i<=10000; $i++) {
    $ret = $redis->getBit('month_loginOnce', $i);
    $ret && $userIds[] = $i;
}

可以看到,在进行or的时候和and还是有些区别的。or的时候,无需对第一次进行判断。个中缘由,大家自己体会体会。

相关专题

更多
c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

22

2026.01.23

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

24

2026.01.23

yy漫画官方登录入口地址合集
yy漫画官方登录入口地址合集

本专题整合了yy漫画入口相关合集,阅读专题下面的文章了解更多详细内容。

99

2026.01.23

漫蛙最新入口地址汇总2026
漫蛙最新入口地址汇总2026

本专题整合了漫蛙最新入口地址大全,阅读专题下面的文章了解更多详细内容。

132

2026.01.23

C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

15

2026.01.23

php远程文件教程合集
php远程文件教程合集

本专题整合了php远程文件相关教程,阅读专题下面的文章了解更多详细内容。

65

2026.01.22

PHP后端开发相关内容汇总
PHP后端开发相关内容汇总

本专题整合了PHP后端开发相关内容,阅读专题下面的文章了解更多详细内容。

61

2026.01.22

php会话教程合集
php会话教程合集

本专题整合了php会话教程相关合集,阅读专题下面的文章了解更多详细内容。

63

2026.01.22

宝塔PHP8.4相关教程汇总
宝塔PHP8.4相关教程汇总

本专题整合了宝塔PHP8.4相关教程,阅读专题下面的文章了解更多详细内容。

33

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

Redis+MySQL数据库面试教程
Redis+MySQL数据库面试教程

共72课时 | 6.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号