最近面试过程中有很多面试官问道了redis,我们都知道redis的基本数据类型有string,hash,list,set,zset,这5个只是最常用的,至少还有2个数据类型Setbit(位操作),GEO(地理位置信息)等等。>5.0还有stream流类型,这个不是今天的重点。今天咱们的重点是基于redis的Setbit实现活跃用户统计功能。

我们来看一个实例吧

场景: 1亿个用户,每个用户登陆/做任意操作,记为 今天活跃,否则记为不活跃。

每周评出: 有奖活跃用户: 连续7天活动

每月评,等等...

其实简单说就是统计一下连续7天(或者连续30天)有多少人连续登陆过

咱们先来想一想传统的方案

很容易就会想到只要用户登陆了,我在表中插入一条数据,并且记录上对应的日期,然后用mysql里面的记录来逐个判断,类似于这样:

Userid   date        active1       2020-07-27  1
1       2020-07-26   1
2       2020-07-27  1
...

但这样是存在一些问题的,主要的问题在于用户量高达1亿,每个用户登陆一次就远远的超过mysql的极限了,更不要说统计一星期了,而且用上group ,sum运算,计算也是非常慢的。所以在这种用户量大,而且统计比较简单的问题上,咱们可以运用位(setbit)操作来解决问题。

先分析一下思路,对于某一天来说,我们可以把这一天想像成一根小木棍,分成了不同的段落,每个段落对应的就是用户的位(因为有user_id),默认值都是0,只要有人登陆了,就把对应的用户的位置标为1即可。

如上图所示,这个就是一天的登陆情况,user_id为6和user_id为8的用户登陆过。其余的都为没有登陆过。因为这个是位操作,所以占的空间很小,1亿的用户,所占的空间也就不到12M。

一天的问题咱们解决了,如何解决他们是否连续登陆过呢?

我们可以用上多个"木棍"

我们可以把每一天作为一个键,然后每天对用户登陆状态进行标记,在最后用每天做一个"与运算"就可以准确的知道哪些用户连续登陆了。

其实总结一下过程如下:

1、记录用户登陆:

每天按日期生成一个位图, 用户登陆后,把user_id位上的bit值置为1

2:、把1周的位图  and 计算,

位上为1的,即是连续登陆的用户

代码实现如下:

redis 127.0.0.1:6379> setbit mon 100000000 0(integer) 0redis 127.0.0.1:6379> setbit mon 3 1(integer) 0redis 127.0.0.1:6379> setbit mon 5 1(integer) 0redis 127.0.0.1:6379> setbit mon 7 1(integer) 0redis 127.0.0.1:6379> setbit thur 100000000 0(integer) 0redis 127.0.0.1:6379> setbit thur 3 1(integer) 0redis 127.0.0.1:6379> setbit thur 5 1(integer) 0redis 127.0.0.1:6379> setbit thur 8 1(integer) 0redis 127.0.0.1:6379> setbit wen 100000000 0(integer) 0redis 127.0.0.1:6379> setbit wen 3 1(integer) 0redis 127.0.0.1:6379> setbit wen 4 1(integer) 0redis 127.0.0.1:6379> setbit wen 6 1(integer) 0redis 127.0.0.1:6379> bitop and  res mon feb wen(integer) 12500001

如上例,优点为:

1、节约空间, 1亿人每天的登陆情况,用1亿bit,约1200WByte,约10M 的字符就能表示;

2、计算方便。

需要注意的是 bitop命令后得到一个12500001 这个返回的是每个key的大小,我们不关注

还要 bitcount res 一下 得出的结果就是活跃用户的数量,当时看别人的博客就写到了bitop

我总是不理解,最后经过和别人讨论,查阅资料才找到了问题所在,这里非常感谢@stone_min

@小齐哥博客,在处理这个问题中的突出贡献!

基于redis实现活跃用户统计功能相关推荐

  1. php redis 签到,基于Redis位图实现用户签到功能

    场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...

  2. 如何用redis做活跃用户统计-HyperLoglog

    原文在这里: 如何用redis做活跃用户统计-HyperLoglog 网站经常有这样的需求:统计日活用户数,有哪些实现方式呢? 第一种做法:用redis的set集合. 用户登录以后,把用户id添加到r ...

  3. 数据统计之日活跃用户统计

    日活跃用户统计 接口分析 请求方式:GET /meiduo_admin/statistical/day_active/ # 日活跃用户统计url(r'^statistical/day_active/$ ...

  4. 基于bootstrap实现简单用户管理功能

    基于bootstrap实现简单用户管理功能,包括增删改以及列表分页展示功能. 1.web.xml配置servlet映射: <servlet><servlet-name>User ...

  5. 【django项目后台开发】数据统计——用户总数统计、日增用户数统计、日活跃用户统计(3)

    一.用户总数统计 1.后端接⼝设计 请求⽅式: GET /statistics/total_count/ 请求参数: 通过请求头传递jwt token数据. 返回数据: JSON { "co ...

  6. SparkCore项目实战 需求一Top10热门品类 需求二Top10热门品类下每个品类的Top10活跃用户统计 需求三计算页面单跳转换率

    目录 数据格式简介 需求一:Top10热门品类(普通算子实现) 优化:需求一(使用ReduceByKey进行预聚合) 优化:需求一(采用累加器,避免shuffle过程) 需求二:Top10热门品类下每 ...

  7. php redis 签到,如何利用 Redis 快速实现签到统计功能

    @这是小豪的第十一篇文章 上篇文章 已经对 Redis 基础命令进行了一个大致的学习,接下来我们就需要解决 Issue "增加用户活跃度统计" 啦! 其实当我看到这个 Issue ...

  8. redis位图法统计活跃用户+统计3天的连续登录用户案例

    Setbit 场景: 1亿个用户, 每个用户 登陆/做任意操作 ,记为今天活跃,否则记为不活跃 用法 周一:1001 0001 1001 0101 1011 0101 周二:1101 0001 101 ...

  9. Spring Boot(五十六):基于Redis的搜索栏热搜功能

    1 功能要求 使用SpringBoot和redis实现一个简单的热搜功能,具备以下功能: 搜索栏展示当前登陆的个人用户的搜索历史记录,删除个人历史记录 用户在搜索栏输入某字符,则将该字符记录下来 以z ...

  10. 移动APP基于支付宝支付实现用户提现功能

    最近公司的项目需要添加一个"提现"功能:用户可以提交申请,将自己账户的钱提出到自己的支付宝账号中. 查了一下发现利用"转账到支付宝账号"可以实现,实现思路:AP ...

最新文章

  1. 李德毅:“反用驾驶脑”测认知能力,谁说酒驾一定违规?
  2. OpenCV-Python:模板匹配
  3. 人工神经网络_AI产品经理必修课 | 人工智能概论(四)-人工神经网络
  4. 前端学习(3265):js中undefine中3相关属性
  5. 为参加脱欧协议表决 英国工党女议员将延后剖腹产
  6. cad编辑节点快捷键是什么_CAD所有快捷键
  7. idea快速查找一个类或类中方法名和变量
  8. python脚本王者荣耀自动刷金币
  9. The authenticity of host ‘172.16.132.189 (172.16.132.189)‘ can‘t be established.
  10. 解决bug-python中关于Process finished with exit code -1073740791
  11. foobar2000-new
  12. HTAP 深入探索指南
  13. 在线学习网站大全(推荐)
  14. Android开源的精美日历控件,热插拔设计的万能自定义UI,你值得拥有
  15. 如何将Android应用发布到Google Play(Android Market)官方市场
  16. 不安抗辩权有哪些规定
  17. java timer 动画_java – 使用Swing动画进行计时
  18. 好程序员web前端教程分享网页设计需要学那些东西?
  19. AES128加密/解密(单片机可用)
  20. 【python编程】使用python获取机器所在网络的公网IP(第一种方法)

热门文章

  1. 《三体》与《西部世界》
  2. 不同火车车型的座位分布图
  3. c语言格式字符二进制,C语言printf如何输出二进制数格式?将十进制数转为二进制输出...
  4. PID调节的C语言及MATLAB实现方法
  5. 川普上台,VR游戏开发者也来恶搞蹭热度
  6. 锂电池电量百分比计算_锂电池的电量、电压与放电时间的计算
  7. 深度估计 双目深度估计+单目深度估计 ONNX运行程序
  8. 敷衍没有出路,iPhone14同时被热捧和唾弃
  9. Zabbix 服务器修改时区时间
  10. php 分段mp4合并,下载一个特殊的m3u8视频并合并为MP4