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内存操作代
替,而且这个东西叫做计算向数据移动,这
redis-bitmap实际运用统计用户登录天数和每天活跃用户相关推荐
- ad域服务器用户登录限制,AD域监控用户登录, 活动目录监控用户, AD登录历史审核...
实时监控用户登录操作 用户登录到其域计算机是在任何企业都会发生的日常活动.一开始,这看起来可能是一个简单的Active Directory事件,但分配有不同角色的管理员可将这个宝贵的数据用于各种审核. ...
- SQL练习题:连续登录5天的活跃用户
题目 写一个 SQL 查询, 找到活跃用户的 id 和 name. 活跃用户是指那些至少连续 5 天登录账户的用户. 返回的结果表按照 id 排序. Accounts 表: id 是该表主键. 该表包 ...
- 小编程(三):用户登录注册界面开发及用户信息管理案例代码详解
用户登录注册界面开发及用户信息管理案例详解 刚开始接触Android编程,这算是我写的第一个简单工程,主要功能有:用户登录.注册.注销.修改密码.记住密码共5个基本操作,其内容涉及到以下几点: 1:B ...
- 【疑问】某省90万中国广电5G用户,只有15%的活跃用户是怎么回事?
今天网友发帖"广电5G发展第一大省,至今发展了90万张卡,但是有85%的卡处于不活跃状态(近一个月没有电话.流量或者短信),这是什么概念?" 昨天,我疑问中国广电到底有多少真实用户 ...
- php开发用户登录模块,使用CodeIgniter开发用户登录注册模块
本文介绍使用CodeIgniter来开发一个用户登录和注册的小模块,有详细的数据库表和ci代码. 1.数据库设计 字段 类型 空 额外 索引 id int(10) 否 auto_increment p ...
- 三层架构用户登录代码c语言,网站用户登录、注册和修改密码常用代码,采用三层架构...
创建用户表的Sql语句,数据库为SQL Server2000: create table "User" ( UserID int not null, UserName varcha ...
- php 单用户登录,Linux 系统的单用户模式、修复模式、跨控制台登录在系统修复中的运用...
一.单用户模式: 单用户模式要求我们输入root用户的密码,否则您无法登录单用户模式:如果您丢失了root用户的密码,并不能用单用户模式来重设您的root密码: 另外单用户模式还有一个前提是您的gru ...
- 用户登录色一句java_用户权限及角色
每个Oracle用户都有一个名字和口令,并拥有一些由其创建的表.视图和其他资源.Oracle角色(role)就是一组权限(privilege)(或者是每个用户根据其状态和条件所需的访问类型).用户可以 ...
- c语言用户登录成功才能,c语言用户登录.docx
} } c 语言登录界面 #include #include void main() { // 界面设计 int j; start: 欢迎使用 XX系统 *************n"); ...
最新文章
- SQL Server索引设计 第五篇
- Android使用NDK OpenGL ES3.0绘制一个三角形
- lua52 C API测试代码
- 星海中学2021高考成绩查询,广东中考时间2021
- Navicat 连接MariaDB 失败: Host '*' is not allowed to connect to this MariaDB server
- 1. 用Ubuntu Server架设基于独立硬盘的Windows文件共享和FTP服务器(概要)
- javascript中encodeURI和decodeURI方法
- Web页面执行shell命令
- 整合 activiti 7 springcloud
- 基于Ansible和CodeDeploy的DevOps解决方案
- time模块时间格式转换及faker库数据伪造
- 编写可读代码的艺术读书整理
- cpe linux -无线 -ap,CPE 是啥?Wi-Fi 6+ 牛在哪儿?一文看懂华为移动路由发展史
- 【戒焦戒躁,can win】Linux--IO缓冲区
- Unix和Linux
- 计算机专业简历教育背景怎么写,简历中教育背景怎么写?填写教育背景注意事项...
- 【深度长文】老IT公司怎么做到像创业公司一样快
- 理解DCT与DST【三】:离散正弦变换
- Shufti Pro宣布获得2000万美元A轮融资以加速发展
- pyqt5制作指示灯