Redis位图法记录在线用户的状态
Redis位图法记录在线用户的状态
位图
Redis官方文档对于位图的介绍如下:
位图不是一个真实的数据类型,而是定义在字符串类型上的面向位的操作的集合。由于字符串类型是二进制安全的二进制大对象,并且最大长度是 512MB,适合于设置 2^32个不同的位。
位操作分为两组:常量时间单个位的操作,像设置一个位为 1 或者 0,或者获取该位的值。对一组位的操作,例如计算指定范围位的置位数量。
位图的最大优势是有时是一种非常显著的节省空间来存储信息的方式。例如,在一个系统中,不同用户由递增的用户 ID 来表示,可以使用 512MB 的内存来表示 400 万用户的单个位信息(例如他们是否需要接收信件)。
简而言之,位图操作是用来操作比特位的,其优点是节省内存空间。为什么可以节省内存空间呢?假如我们需要存储100万个用户的登录状态,使用位图的话最少只需要100万个比特位(比特位1表示登录,比特位0表示未登录)就可以存储了,而如果以字符串的形式存储,比如说以userId为key,是否登录(字符串“1”表示登录,字符串“0”表示未登录)为value进行存储的话,就需要存储100万个字符串了,相比之下使用位图存储占用的空间要小得多,这就是位图存储的优势。
问题引出
如何有效统计:
1:如何记录用户的登陆情况
2:如何查询活跃用户(连续登陆)
思路
构造一个位图,里面存的是二进制数据,如:1 0 1 0 1 0 1,通过修改userId对应位置上的0和1来修改用户在线状态,由于默认值为0,所以1代表用户处于在线状态,0代表用户处于离线状态,如图:

构造了Mon、Thus、Web三个位图,对于Mon来说,userId=1的用户处于在线状态,userId=2的用户处于离线状态,userId=3的用户处于在线状态,当userId=10的用户上线后,就把第10位上值变成1
空间预估
二进制数据1位为1bit
1千兆字节(gb)=8589934592比特(bit)
理论上1G的内存可以记录85亿多的用户状态,如果userId不连贯,有的userId位数超过85亿位,可以使用一些算法、或者对userId按位分段来解决
实例
假设现在有八个用户
Uid: 1 2 3 4 5 6 7 8
周一 : 0 1 0 1 0 0 0 1
周二 : 0 1 1 1 0 1 0 1
周三 : 1 1 0 1 1 0 0 1
周四 : 0 1 0 1 0 1 0 1
周五 : 1 1 0 1 1 0 1 1
周六 : 0 1 0 0 0 1 1 1
周七 : 0 1 0 1 0 0 0 1
我们如何统计一周连续登陆的用户呢?(按位与)
一周连续登陆:01000001:二号用户和八号用户连续登陆
使用命令
setbit key offset value 修改key中,第offset位的值为value
getbit key offset 获取key中,第offset位上的value
bitcount key 统计key中,1的个数
itop op destKey key1 key2 ….. 其中op可以为AND(于)、OR(或)、NOT(非)、XOR(异或)
命令的主要作用是,给key1、key2..等,这种二进制数据,按位做逻辑运算,结果付到destkey中,没有setbit的位置默认为0
演示
Uid: 1 2 3 4 5 6 7 8
周一 : 0 1 0 1 0 0 0 1
周二 : 0 1 1 1 0 1 0 1
周三 : 1 1 0 1 1 0 0 1
redis 127.0.0.1:6379>setbit mon 8 0
(integer) 0
redis 127.0.0.1:6379>setbit mon 2 1
(integer) 0
redis 127.0.0.1:6379>setbit mon 3 1
(integer) 0
redis 127.0.0.1:6379>setbit mon 8 1
(integer) 0 redis 127.0.0.1:6379>setbit feb 8 0
(integer) 0
redis 127.0.0.1:6379>setbit feb 2 1
(integer) 0
redis 127.0.0.1:6379>setbit feb 3 1
(integer) 0
redis 127.0.0.1:6379>setbit feb 4 1
(integer) 0
redis 127.0.0.1:6379>setbit feb 6 1
(integer) 0
redis 127.0.0.1:6379>setbit feb 8 1
(integer) 0 redis 127.0.0.1:6379>setbit wen 8 0
(integer) 0
redis 127.0.0.1:6379>setbit wen 1 1
(integer) 0
redis 127.0.0.1:6379>setbit wen 2 1
(integer) 0
redis 127.0.0.1:6379>setbit wen 4 1
(integer) 0
redis 127.0.0.1:6379>setbit wen 5 1
(integer) 0
redis 127.0.0.1:6379>setbit wen 8 1
(integer) 0 redis 127.0.0.1:6379>bitop and res mon feb wen #最后得出结果
Redis位图法记录在线用户的状态的更多相关文章
- 05 redis中的Setbit位图法统计活跃用户
一:场景=>>>长轮询Ajax,在线聊天时,能够用到 Setbit 的实际应用 场景: 1亿个用户, 每个用户 登陆/做任意操作 ,记为 今天活跃,否则记为不活跃 每周评出: 有奖活 ...
- 使用 Redis 统计在线用户人数
在构建应用的时候, 我们经常需要对用户的一举一动进行记录, 而其中一个比较重要的操作, 就是对在线的用户进行记录. 本文将介绍四种使用 Redis 对在线用户进行记录的方案, 这些方案虽然都可以对在线 ...
- 在线用户管理--ESFramework 4.0 进阶(05)
无论我们采用何种通信框架来构建我们的分布式系统,在服务端进行用户管理都是非常重要的一个环节.然而用户管理是否应该隶属于通信框架了?这个并不一定,通常来说,用户管理是与具体应用紧密相关的,应该是由应用解 ...
- node 全局对象global —— 记录在线人员
最近做毕设的时候,在做查看在线人员这个功能的时候,一直卡顿,我的思路是数据库保存 是否在线 字段,可以在登录时和退出系统修改状态,但如果用户之间关闭窗口时候就没办法向后台发出修改在线状态的请求.我想到 ...
- 基于Redis的在线用户列表解决方案
前言: 由于项目需求,需要在集群环境下实现在线用户列表的功能,并依靠在线列表实现用户单一登陆(同一账户只能一处登陆)功能: 在单机环境下,在线列表的实现方案可以采用SessionListener来完成 ...
- [项目回顾]基于Redis的在线用户列表解决方案
迁移:基于Redis的在线用户列表解决方案 前言: 由于项目需求,需要在集群环境下实现在线用户列表的功能,并依靠在线列表实现用户单一登陆(同一账户只能一处登陆)功能: 在单机环境下,在线列表的实现方案 ...
- 基于Redis位图实现系统用户登录统计
项目需求,试着写了一个简单登录统计,基本功能都实现了,日志数据量小.具体性能没有进行测试~ 记录下开发过程与代码,留着以后改进! 1. 需求 1. 实现记录用户哪天进行了登录,每天只记录是否登录过,重 ...
- Redis位图实现用户签到功能
场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...
- 基于Redis位图实现用户签到功能
场景需求 适用场景如签到送积分.签到领取奖励等,大致需求如下: 签到1天送1积分,连续签到2天送2积分,3天送3积分,3天以上均送3积分等. 如果连续签到中断,则重置计数,每月初重置计数. 当月签到满 ...
随机推荐
- Visual Studio UI Automation 学习(一)
这几天需要研究自动化测试工具,因为团队开发使用visual studio,所以需要研究一下Visual studio自带的框架. 刚开始安装的时候,没有选自定义安装,所以安装完成后没有找到UI Aut ...
- kafka概述与下一代消息队列
常用的消息中间件 消息中间件是当前处理大数据的一个非常重要的组件,用来解决应用解耦.异步通信.流量控制等问题,从而构建一个高效.灵活.消息同步和异步传输处理.存储转发.可伸缩和最终一致性的稳定系统.目 ...
- js与Jquery的对比
// document.getElementById("divCommit").style.display="none";// document.g ...
- 团体程序设计天梯赛-练习集-L1-039. 古风排版
L1-039. 古风排版 中国的古人写文字,是从右向左竖向排版的.本题就请你编写程序,把一段文字按古风排版. 输入格式: 输入在第一行给出一个正整数N(<100),是每一列的字符数.第二行给出一 ...
- 团体程序设计天梯赛-练习集-L1-032. Left-pad
L1-032. Left-pad 根据新浪微博上的消息,有一位开发者不满NPM(Node Package Manager)的做法,收回了自己的开源代码,其中包括一个叫left-pad的模块,就是这个模 ...
- Django解决跨域俩方案
方案一:一套干掉全部Primary 首先你的pip下载一个第三方库贼厉害的: pip install corsheaders 然后在项目的setting.py里面引入第三方库,如下: INSTALLE ...
- tp5 前置方法
Route::any('adminapi/v1/login','adminapi/v1.login/login');Route::any('adminapi/v1/first','adminapi/v ...
- php unlink()函数使用
最近在写个网站,需要上传图片,如果修改图片,就图片就没有用了,会占用服务器的硬盘资源,所以想到用unlink函数删除旧照片. 问题 : unlink函数只能删除 相对于函数执行文件的相对目录 或 ...
- HDU 2795 Billboard (线段树+贪心)
手动博客搬家:本文发表于20170822 21:30:17, 原地址https://blog.csdn.net/suncongbo/article/details/77488127 URL: http ...
- 【微软2017年预科生计划在线编程笔试第二场 B】Diligent Robots
[题目链接]:http://hihocoder.com/problemset/problem/1498 [题意] 一开始你有1个机器人; 你有n个工作; 每个工作都需要一个机器人花1小时完成; 然后每 ...