您当前的位置:首页 > 电脑百科 > 数据库 > Redis

Redis 位图基础到统计活跃用户

时间:2020-03-10 13:36:59  来源:  作者:

大家有没有想过如何统计活跃用户数量?如果是自己做,那该怎么做?

这里思考一分钟,后面我将分享一下如何使用 redis 中的位图来统计活跃用户数。

正文

什么是位图 ?

位图(bitmap)是二进制的 byte 数组 ,也可以简单理解成是一个普通字符串。它将二进制数据存储在 byte 数组中以达到存储数据的作用。

Redis 位图基础到统计活跃用户

 

图 1.1

如何使用位图 ?

理清概念

在解释什么是位图的时候说过,位图可以理解成是一个普通字符串, 那么我们为什么要用位图而不是字符串呢 ?

下面是在 redis 中存储字符串的一个示意图

Redis 位图基础到统计活跃用户

 

图 2.1

如图,存储字符串是将字符串二进制数组的形式存储在 redis 中,位图可以直接对 二进制的数组操作, 位图的优势在于可以用 0 和 1来存储布尔值,这大大降低了我们的存储空间消耗 。由于这个特性,我们 用位图来记录签到信息,记录活跃用户等 ,可以达到节省空间的能力(后面会有介绍)。

那我们如何对二进制的数组进行操作呢?

基本存取

setbit | getbit

上文说的二进制数组我们可以对它做 添加、查找及修改 的功能

如何进行添加和查找呢?

setbit [keyName] [offset] [value]

offset:偏移量,指的是数组的下标; value: 数据, 只能是 0 和 1。

这条命令既可以添加数据也可以修改数据。

如何进行查找呢 ?

getbit [keyName] [offset]

offset:偏移量,指的是数组的下标。这里,除了设置 value 为 1 的 offset, 查询其他的都返回 0

补充:上面说了位图可以理解成字符串,那么它们之间可以互相操作吗?

Redis 位图基础到统计活跃用户

 

图 2.2

请对照上图,我们一起完成下面的探究:

  1. 以字符串存储,可以通过 getbit 命令获取到值吗?我们可以结合查询和图片所示的 offset 及所对应的值来验证> set str hi OK > getbit str 0 (integer) 0 > getbit str 4 (integer) 1 > getbit str 7 (integer) 0 > getbit str 15 (integer) 1 复制代码结论:可以的
  2. 以字符串存储,可以通过 settbit 修改值吗?我们可以试着将 offset 7 对应的 value 改成 1, 如果成功了,h 字符应该变成 i> setbit str 7 1 (integer) 0 > get str "ii" 复制代码结论:可以
  3. 用 setbit 存储字符串的二进制数据,可以通过 get 获取字符串吗?我们将 字符 h 的二进制存入位图,看可以能通过 get 获取> setbit bitmap 0 0 (integer) 0 > setbit bitmap 1 1 (integer) 0 > setbit bitmap 2 1 (integer) 0 > setbit bitmap 3 0 (integer) 0 > setbit bitmap 4 1 (integer) 0 > setbit bitmap 5 0 (integer) 0 > setbit bitmap 6 0 (integer) 0 > setbit bitmap 7 0 (integer) 0 > get bitmap "h" 复制代码结论:可以

上面介绍了位图的基本概念和使用,通过一系列的探究希望能帮助大家更好的理解位图

那么,如何将位图应用的项目中呢?

统计和查找

bitcount | bitpos

bitcount 是用来查找 1 出现的次数,既可以对位图使用也可以对字符串使用 ,用法如下:

bitcount [keyName] [startWith] [endWith]

注意:这里的 startWith 和 endWith 不是二进制数组的下标(offset)

这里的 startWith 和 endWith 可以理解成是字符串的下标,一个字符串对应 8 位二进制数据;它们相当于是截取字符串,如 s= "hi" , s[0:0] = "h" , 它所对应的二进制数组的下标是 0,7,以此类推。

其实这里不好解释,先来带代码,可以结合着上面的 图 2.2 看一下,大家后面可以在领悟一下

> set str hi
> bitcount str 0 0
(integer) 4
> bitcount str 0 1
(integer) 8
> bitcount str
(integer) 8

注意:startWith 和 endWith 不设置的时候默认全部范围

应用场景: 统计活跃用户的数量

bitpos 用来查找指定范围内出现的第一个 0 或 1 ,用法如下:

bitpos [keyName] [bit] [start] [end]

bit: 要找的 0 或者 1, start 和 end 同上面的 startWith 和 endWith

应用场景: 获取第一次签到和第一次未签到的时间

应用场景

上面大致说了 2 个应用场景:

  1. 统计活跃用户的数量
  2. 获取第一次签到和第一次未签到的时间

我在这里稍微介绍一下思路,然后附上一个 统计活跃用户的数量 可供参考

统计活跃用户的数量

  1. 将位图的 keyName 设置成需要统计的 行为和时间范围 [ation:date], 如: login:2020-3
  2. 将用户对应到位图中的 offset , 如 id 对应二进制数组的下标, id 为 int
  3. 签到成功使用 setbit 将对应的 offset 设置成 1
  4. 使用 bitcount 统计某个 行为和时间范围 的活跃人数,如 bitcount login:2020-3

Demo: DailyActiveUsers

获取第一次签到和第一次未签到的时间

  1. 将位图的 keyName 设置成需要统计的 行为和时间范围和对象 [ation: date:person], 如: login:2020-3:Tom
  2. 将日期对应到位图中的 offset , 如 1号对应二进制数组的下标 0, 2 号为 1
  3. 签到成功使用 setbit 将对应的 offset 设置成 1
  4. 使用 bitpos 统计某个 行为和时间范围和对象 的签到情况,如 bitpos login:2020-3:Tom 1


Tags:Redis   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
来源: my.oschina.net/xiaomu0082/blog/2990388首先说下问题现象:内网sandbox环境API持续1周出现应用卡死,所有api无响应现象刚开始当测试抱怨环境响应慢的时候 ,我们重启一下应...【详细内容】
2021-12-08  Tags: Redis  点击:(18)  评论:(0)  加入收藏
我不知道为什么你会选择对特定数量的“错误”(或警告)如此具体。听起来您正在寻找将要发布到 Yahoo! 的某些文章的内容。 Insider (N Foos to Blah for the BlahBlah)。那说:...【详细内容】
2021-12-07  Tags: Redis  点击:(14)  评论:(0)  加入收藏
目录 一、背景 二、步骤 0.理论支持 1、获取数据 2、结果 3、分析数据并评估大小 三、关于repl-backlog-size 一、背景 repl-backlog-size控制这个环形缓冲区. ​ 主从断...【详细内容】
2021-11-05  Tags: Redis  点击:(41)  评论:(0)  加入收藏
Redis 性能测试是通过同时执行多个命令实现的。1,Redis-benchmarkRedis性能命令:redis性能命令格式: redis-benchmark [option] [option value] redis 性能测试工具可选参数如...【详细内容】
2021-11-02  Tags: Redis  点击:(41)  评论:(0)  加入收藏
1 概述数据结构和内部编码 无传统关系型数据库的 Table 模型schema 所对应的db仅以编号区分。同一 db 内,key 作为顶层模型,它的值是扁平化的。即 db 就是key的命名空间。 key...【详细内容】
2021-11-01  Tags: Redis  点击:(28)  评论:(0)  加入收藏
普通java中使用引用Java redis 驱动,即可连接:import redis.clients.jedis.Jedis; public class RedisTestJava { public static void main(String[] args) { //连...【详细内容】
2021-10-13  Tags: Redis  点击:(34)  评论:(0)  加入收藏
Redis常用的数据结构有 string list set zset hashstringstring 是 Redis 的基本的数据类型,一个 key 对应一个 value。string 类型是二进制安全的,Redis的string可以包含任...【详细内容】
2021-10-12  Tags: Redis  点击:(36)  评论:(0)  加入收藏
列表类型可以存储一组按插入顺序排序的字符串,它非常灵活,支持在两端插入、弹出数据,可以充当栈和队列的角色。> LPUSH fruit apple(integer) 1> RPUSH fruit banana(integer)...【详细内容】
2021-09-17  Tags: Redis  点击:(54)  评论:(0)  加入收藏
Redis持久化意义 是做灾难恢复,数据恢复,也可以归类到高可用的一个环节里面去,比如你的redis整个挂了,然后redis就不可用了,你要做的事情是让redis变得可用,尽快变得可用 大量的请...【详细内容】
2021-08-12  Tags: Redis  点击:(77)  评论:(0)  加入收藏
Nginx来限制访问控制的方法有多种,nginx主要有2个模块控制,但是那些不支持自定义,非常死,在大多数场景下并不实用。今天分享一个:利用openresty+lua+redis 实现封杀频繁恶意访问I...【详细内容】
2021-08-12  Tags: Redis  点击:(119)  评论:(0)  加入收藏
▌简易百科推荐
来源: my.oschina.net/xiaomu0082/blog/2990388首先说下问题现象:内网sandbox环境API持续1周出现应用卡死,所有api无响应现象刚开始当测试抱怨环境响应慢的时候 ,我们重启一下应...【详细内容】
2021-12-08  Java识堂    Tags:Redis   点击:(18)  评论:(0)  加入收藏
我不知道为什么你会选择对特定数量的“错误”(或警告)如此具体。听起来您正在寻找将要发布到 Yahoo! 的某些文章的内容。 Insider (N Foos to Blah for the BlahBlah)。那说:...【详细内容】
2021-12-07  富集云科技有限公司    Tags:Redis   点击:(14)  评论:(0)  加入收藏
目录 一、背景 二、步骤 0.理论支持 1、获取数据 2、结果 3、分析数据并评估大小 三、关于repl-backlog-size 一、背景 repl-backlog-size控制这个环形缓冲区. ​ 主从断...【详细内容】
2021-11-05  弈秋的美好生活    Tags:redis   点击:(41)  评论:(0)  加入收藏
Redis 性能测试是通过同时执行多个命令实现的。1,Redis-benchmarkRedis性能命令:redis性能命令格式: redis-benchmark [option] [option value] redis 性能测试工具可选参数如...【详细内容】
2021-11-02  川石信息    Tags:Redis   点击:(41)  评论:(0)  加入收藏
1 概述数据结构和内部编码 无传统关系型数据库的 Table 模型schema 所对应的db仅以编号区分。同一 db 内,key 作为顶层模型,它的值是扁平化的。即 db 就是key的命名空间。 key...【详细内容】
2021-11-01  JavaEdge    Tags:Redis   点击:(28)  评论:(0)  加入收藏
普通java中使用引用Java redis 驱动,即可连接:import redis.clients.jedis.Jedis; public class RedisTestJava { public static void main(String[] args) { //连...【详细内容】
2021-10-13  faesuite    Tags:Redis   点击:(34)  评论:(0)  加入收藏
Redis常用的数据结构有 string list set zset hashstringstring 是 Redis 的基本的数据类型,一个 key 对应一个 value。string 类型是二进制安全的,Redis的string可以包含任...【详细内容】
2021-10-12  语霖    Tags:Redis   点击:(36)  评论:(0)  加入收藏
列表类型可以存储一组按插入顺序排序的字符串,它非常灵活,支持在两端插入、弹出数据,可以充当栈和队列的角色。> LPUSH fruit apple(integer) 1> RPUSH fruit banana(integer)...【详细内容】
2021-09-17  深夜敲代码    Tags:Redis   点击:(54)  评论:(0)  加入收藏
Redis持久化意义 是做灾难恢复,数据恢复,也可以归类到高可用的一个环节里面去,比如你的redis整个挂了,然后redis就不可用了,你要做的事情是让redis变得可用,尽快变得可用 大量的请...【详细内容】
2021-08-12  小李说IT    Tags:Redis   点击:(77)  评论:(0)  加入收藏
当查询Redis中没有的数据时,该查询会下沉到数据库层,同时数据库层也没有该数据,当这种情况大量出现或被恶意攻击时,接口的访问全部透过Redis访问数据库,而数据库中也没有这些数据...【详细内容】
2021-07-30  随便t    Tags:缓存穿透   点击:(91)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条