用redis的bitmap方式统计上亿访问量的周活跃用户

news/2024/7/7 19:48:55 标签: 数据库, java

提出问题

网站每天有1亿的访问量,产品提出要统计每个uid的周活跃,目前是日志分析解决的,每天有20G的日志,公司有dip平台会用日志去计算,每次要计算两小时才能处理完。

分析问题

考虑了一下是否可以用redis的bitmap的方式来做一个统计周活跃的功能

先简单说下bitmap的原理: 假设有3个同学:

小明 1小明 2小明 3

如果有三间房,0是男,女是1,

房1房2房2
011

如果要统计现在班上有几位女生,就可以看到两个1就是两位女生

在计算机里,一个字节里有8个二进制位,即1byte=8bit 假设有7个数字,我们可以按照编号放进一段连续内存里,对应位置中存在就显示1,其它默认都显示0 比如 3,5,1,7,11,15,4,1 那对应的位置为:

byte0  0 1 0 1 0 1 0 1
byte1  0 0 0 1 0 0 0 1
复制代码

很明显我们已经方便的对这些数字做了排序了,甚至还做了排重 如果我们要找7是否存在这个数组中,

只需要7/8 对应到第一个字节byte0中
7%8对应到第7位上,如果是1就存在,0就不存在。
复制代码

如果两亿的数字做排序排重,我们大概要占用好几G的空间,如果用bitmap方式,最少只需要200000000/8/1024/1024 = 24M的空间就够了

接下来我们看看bitmap在redis上的应用:

假设这是我们uid的登录情况 0代表未登录,1代表登录

Monday
8987129 0
8298191 1
8892198 1

Tuesday
8987129 0
8298191 0
8892198 1

Wednesday
8987129 1
8298191 1
8892198 1

Thursday
8987129 0
8298191 0
8892198 0

Friday
8987129 0
8298191 1
8892198 1

Saturday
8987129 0
8298191 1
8892198 0

Sunday
8987129 1
8298191 1
8892198 0
复制代码

用setbit方法,将这些数据录入到redis中:

setbit key offset value
设置offset对应二进制上的值,返回该位上的旧值

注意:如果offset过大,则会在中间填充0
   offset最大到2^32-1,即可推出最大的字符串为512M
复制代码
127.0.0.1:6379> setbit Monday 8987129 0
(integer) 0
127.0.0.1:6379> setbit Monday 8298191 1
(integer) 0
127.0.0.1:6379> setbit Monday 8892198 1
(integer) 0
127.0.0.1:6379> setbit Tuesday 8987129 0
(integer) 0
127.0.0.1:6379> setbit Tuesday 8298191 0
(integer) 0
127.0.0.1:6379> setbit Tuesday 8892198 1
(integer) 0
127.0.0.1:6379> setbit Wednesday 8987129 0
(integer) 0
127.0.0.1:6379> setbit Wednesday 8298191 1
(integer) 0
127.0.0.1:6379> setbit Wednesday 8892198 1
(integer) 0
127.0.0.1:6379> setbit Thursday 8987129 0
(integer) 0
127.0.0.1:6379> setbit Thursday 8298191 0
(integer) 0
127.0.0.1:6379> setbit Thursday 8892198 0
(integer) 0
127.0.0.1:6379> setbit Friday 8987129 0
(integer) 0
127.0.0.1:6379> setbit Friday 8298191 1
(integer) 0
127.0.0.1:6379> setbit Friday 8892198 1
(integer) 0
127.0.0.1:6379> setbit Saturday 8987129 0
(integer) 0
127.0.0.1:6379> setbit Saturday 8298191 1
(integer) 0
127.0.0.1:6379> setbit Saturday 8892198 0
(integer) 0
127.0.0.1:6379> setbit Sunday 8987129 0
(integer) 0
127.0.0.1:6379> setbit Sunday 8298191 1
(integer) 0
127.0.0.1:6379> setbit Sunday 8892198 0
(integer) 0
复制代码

接下来要计算7天内有登录行为的用户,只需要将周一到周五的值做位或运算就可以了

补充下位与运算符:

按位与运算符(&)
参加运算的两个数据,按二进制位进行“与”运算。
运算规则:0&0=0;  0&1=0;   1&0=0;    1&1=1;
    即:两位同时为“1”,结果才为“1”,否则为0
      
按位或运算符(|)
参加运算的两个对象,按二进制位进行“或”运算。
运算规则:0|0=0;  0|1=1;  1|0=1;   1|1=1;
    即 :参加运算的两个对象只要有一个为1,其值为1。
     
异或运算符(^)
参加运算的两个数据,按二进制位进行“异或”运算。
运算规则:0^0=0;  0^1=1;  1^0=1;   1^1=0;
即:参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
复制代码

最后计算7天内登录过的活跃用户:

    127.0.0.1:6379> bitop OR result Monday Tuesday Wednesday Thursday Friday Saturday Sunday
复制代码
bitop operation rs key1 [key2..]    
对key1 key2做opecation并将结果保存在rs上
opecation可以是AND(与) OR(或) NOT(非) XOR(异或)
复制代码

                                                     

这里计算的结果假设3个uid都是连续的话就是 110,其实可能是 ...1.....1....0...... 也就是本周有两个活跃用户登录过。

就这样,一个上亿访问量的日志统计,在redis的bitmap方式轻松解决。


http://www.niftyadmin.cn/n/960969.html

相关文章

linux env /printenv/fw_printenv区别

fw_printenv(自己也可定义): 可以打印出在uboot中设置的环境变量的值。env/printenv 都是打印当系统环境变量。 不同的是printenv不加参数和env一样,printenv可以打印指定名称的环境变量 实现: simonbearsimonbear-V…

人工智能是计算机辅助翻译吗,人工智能背景下计算机辅助翻译在中国的研究现状述评原稿(图文高清版)...

人工智能背景下计算机辅助翻译在中国的研究现状述评(原稿)1、的‚即时视觉翻译‛通过摄像头即时取词翻译,利用增强现实技术把翻译后的文字原封不动地呈现在原来文字的位臵,则相当于人工同声传译人,哈尔滨师范大学级硕士研究生,院系为西语学院,研究方向为学科教学英语。。计算机…

安卓8.0静态注册广播不能用的问题

静态注册广播,但是发现接收不到广播 解决方案如下: 在intent里面加 component(“广播接收者的报名”,“广播接收者路径”) 这样就能收到了 如下图: 查了下源码发现 Beginning with Android 8.0 (API le…

Spring中的BeanPostProcessor

一、何谓BeanProcessor BeanPostProcessor是SpringFramework里非常重要的核心接口之一,我先贴出一段源代码: /** Copyright 2002-2015 the original author or authors.** Licensed under the Apache License, Version 2.0 (the "License");* …

深圳大学计算机博士好考吗,深圳大学在职博士好考吗?

目前关于深圳大学在职研究生入学难度,是很多报考人员比较关注的信息。而该校在职研入学难度与报考方式相关,学员选择本校攻读在职研究生,可报考同等学力。深圳大学在职博士好考吗?一、报考基本条件考生的学位必须符合下列条件之一…

全球调研显示:智能自动化将增强员工能力

埃维诺的一项研究强调,在未来三年内,企业需采用智能自动化来推动生产力发展,并持续利用创新脱颖而出。 研究发现,逾半数全球商业领袖相信智能自动化将增强员工能力,而非取代工作岗位。的确,许多企业由于单纯…

cisco服务器桌面命令行窗口,cisco设置

cisco路由向来以难配置而绝不天下。那么cisco怎么设置vlan ip?学习啦小编整理了相关资料,给大家介绍。有需要学习的同学可参考参考。cisco设置vlan ip步骤1.1.交换机启动需要大约4-5分钟;1.2.网线插入交换机接口从黄变为绿需要大约1-2分钟,即进入正常工…

virtubox+Ubuntu com1 ttyS0 com8 ttyUSB0配置

一.com1配置 二.com8 ttyUSB0配置 simonbearsimonbear-VirtualBox:~$ dmesg | grep ttyUSB0 [ 16.304071] usb 2-2: pl2303 converter now attached to ttyUSB0 [ 613.411371] pl2303 ttyUSB0: pl2303_set_control_lines - failed: -19 [ 613.415927] pl2303 ttyUSB0: pl2303…