redis-bitmap实际运用统计用户登录天数和每天活跃用户

redis bitmap实际运用一统计用户登录天数

第一个听需求如果你的公司有用户系统,有很多用户。然后这时候需求是什么?
统计未来用户的登录天数,且窗口随机。什么意思?比如说在电商的公司当中,电商的网
站,一般就是老板心血来潮说,今天是8月28 ,马上就9月了,那么9月1号往前推一周,9月
1号往后推一周,这14天所有用户的登录的天数帮我统计一下,然后没过两天该是双11了,
双11的前后帮我统计一下,然后哪天他老婆生日了,我老婆生日前后几天给我统计一下,
你的老板会随机的让你统计,指不定哪天开始哪天结束,就在这个范围之内。
使用关系型数据库实现
拿一个数据库MYSQL,然后创建一张用户登录表,用户每一笔登录是不是可以在里面产生一行记录,然后登记他登陆的时间,然后用户所有东西都往那里灌,但是这时候,你想一想,这样的存储是不是就要存用户的ID,因为MYSQL是关系型数据库,它表与表之间必然有一个主外键对不对?关联对不对?所以这个ID可能就是几个字节了,最少得三四个字节存一个ID。咱们现在在算成本复杂度,这张表最少,每行是不是得存一个日期,再存一个,他哪天登陆的,日期的话你最少也得准备4个字节,ID你得准备4个字节,所以使用的关键数据库的时候,表示1个用户的一笔登录要消耗8个字节。这是第一反应。那么京东有多少人?每个人一年基本上得有200多天登陆,这张表的数据是不是极其大?查询的时候老板给出一个随机窗口,是不是要遍历所有的数据,成本是不是极其的高?怎么优化
用bitmap解决
姓名作为redis的k,用bitmap,一个字符是8个二进制位,0代表没登录,1代表登录;因为二进制位在字符是连续的从0开始一直累加,0代表第一天,一代表第二天


127.0.0.1:6379> setbit zyz 0 1
(integer) 0
127.0.0.1:6379> setbit zyz 7 1
(integer) 0
127.0.0.1:6379> setbit zyz 18 1
(integer) 0
127.0.0.1:6379> setbit zyz 99 1
(integer) 0
127.0.0.1:6379> setbit zyz 78 1
(integer) 0
127.0.0.1:6379> BITCOUNT zyz
(integer) 5
127.0.0.1:6379> BITCOUNT zyz 12 13
(integer) 1
127.0.0.1:6379> setbit zyz 95 1
(integer) 0
127.0.0.1:6379> BITCOUNT zyz 12 13
(integer) 1
127.0.0.1:6379> BITCOUNT zyz 11 13
(integer) 2
127.0.0.1:6379> BITCOUNT zyz -2 -1
(integer) 2
127.0.0.1:6379> 
    01 02 03 04 05
zyz 0  1  0  1  0  1
wyy 0  1  0  0  0  0

算一个成本,这里面有两个固定的数值,第一个固定的数值就是一年有365天或者366天对不对?我大方一点,1年400天,如果每一天对应一个二进制位,就是从左向右,第一个二进制位代表第一天,第二个二进制位代表第二天,也就是400个二进制位,400÷8是50个字节,用50个字节可以最大记录一个用户全年365天的登录状态。
不只是主要节省空间,二进制位的操作在计算机系统当中CPU计算的速度是最快的。你想想如果把它换成官型数据库的话,他肯定是读磁盘,第一个产生磁盘I/O,第二个,读到磁盘之后,然后他还需要将读回来的数据编码解码,然后再参与一些计算,而且绝对不是不会二进制位的计算。

redis bitmap实际运用二—统计最近一段日期每天的活跃用户

统计最近一段日期每天的活跃用户,
日期作为k,二进制位绑定用户ID,1代表登录,2代表未登录

127.0.0.1:6379> setbit 20211220 0 1
(integer) 0
127.0.0.1:6379> setbit 20211220 1 1
(integer) 0
127.0.0.1:6379> setbit 20211220 4 1
(integer) 0
127.0.0.1:6379> setbit 20211220 9 1
(integer) 0
127.0.0.1:6379> SETBIT 20211221 0 1
(integer) 0
127.0.0.1:6379> SETBIT 20211221 1 1
(integer) 0
127.0.0.1:6379> SETBIT 20211221 5 1
(integer) 0
127.0.0.1:6379> SETBIT 20211221 52 1
(integer) 0
127.0.0.1:6379> BITCOUNT 20211220
(integer) 4
127.0.0.1:6379> BITCOUNT 20211221
(integer) 4
127.0.0.1:6379> BITOP and huo 20211220 20211221  去重复 同一个用户每天都登录 则只计算一次
(integer) 7
127.0.0.1:6379> BITCOUNT huo
(integer) 2
127.0.0.1:6379> BITCOUNT huo 0 -1
(integer) 2
127.0.0.1:6379> 

主要使用的原因就是占用的存储空间小并且在内存操作,二进制位运算,速度较快
encoding的话也可以规避你后续直接拓穿到拿这个字节拿出来直接做计算这个事,可以在前面挡一次。这能听懂吧?然后他是有这些东西,然后strlen,其实你的value的长度,strlen当中可以当对象,也会保存,因为只要你做增删改这个value了,同时把这个长度算完之后,后边如果1亿次并发查询的话,不需要再重复计算长度,长度直接返回,因为你从来再没有改过它,所以这是作者在 k上的小心思,他让我们的redis虽然是单线程,但是有一些操作都会预埋下来,完成对后续高并发地查询速度极快地返回,基本都是O1的复杂度

面向数值计算的场景,其实比如就是我们的抢购商品的秒杀。秒杀还有详情页,
像淘宝的详情页,详情页当中大部份静态的图片中的信息,但是他一定会后端发起一个异
步查询,查询你这个商品的所有的购买数,然后等等一系列东西。所以这个时候如果redis
没有这个数值,没有incr、decr的话,你要到数据库的话,等于一个并行度的多个人想去同
时对一个商品加减的话,必然会触发数据库的事物,对不对?所以这时候其实如果有了这
种redis对数值类型的话,可以规避并发下, 对数据库的事务操作,完全由redis内存操作代
替,而且这个东西叫做计算向数据移动,这

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值