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

前言

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

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

正文

什么是位图 ?

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

图 1.1

如何使用位图 ?

理清概念

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

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


图 2.1

![setbit.png](https://upload-images.jianshu.io/upload_images/14961694-3ecf37534fa88624.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

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

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

基本存取

setbit | getbit

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

如何进行添加和查找呢?

setbit [keyName] [offset] [value]

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

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

如何进行查找呢 ?

getbit [keyName] [offset]

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

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

图 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 对应二进制数组的下标,idint
  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

总结

  1. 位图和字符串没有本质上的区别,只是操作方式不同
  2. 使用位图存储布尔数据可以大大节省空间
  3. 存取命令 setbit/getbit
  4. 统计查找 bitcount / bitpos

最后

上述内容对大家有所帮助的话,请帮我 点个赞👍,分享不易,感谢支持!

如果本文有任何错误,感谢各位批评指教 !

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容

  • 一亿个用户,有的用户频繁登录,也有不经常登录的。如何记录用户的登录信息?如何查询活跃用户?[如一周内 登录三次的]...
    小胖学编程阅读 8,531评论 0 12
  • 基本的Redis key的操作都已经熟悉了之后,便可以开始针对Redis提供的各种可操作的数据结构进行学习和了解。...
    Yorking阅读 858评论 0 0
  • 什么是位图 位图(Bitmap)是通过一个 bit 来表示某个元素对应的值或者状态。它并不是什么新的数据结构。它的...
    youthcity阅读 2,042评论 1 51
  • 一、大家觉得在PPT中什么样的表格样式才算美观大方、重点突出。 二、美化表格四步骤如下: 001.去除格式 002...
    E15期4队一五彩云一万州阅读 149评论 0 1
  • #八岁日记#略凌乱~ 继我回京一周后,老妈也结束了二十多天的杭州之行,启程回家~昨天闲来无事一起翻看照片,又让我想...
    妖八岁阅读 232评论 0 0