Redis 位圖基礎到統計活躍用戶

前言

你們有沒有想過如何統計活躍用戶數量?若是是本身作,那該怎麼作?git

這裏思考一分鐘,後面我將分享一下如何使用 redis 中的位圖來統計活躍用戶數。github

正文

什麼是位圖 ?

位圖(bitmap) 是二進制的 byte 數組,也能夠簡單理解成是一個普通字符串。它將二進制數據存儲在 byte 數組中以達到存儲數據的做用。redis

圖 1.1數組

如何使用位圖 ?

理清概念

在解釋什麼是位圖的時候說過,位圖能夠理解成是一個普通字符串,那麼咱們爲何要用位圖而不是字符串呢 ?markdown

下面是在 redis 中存儲字符串的一個示意圖oop

圖 2.1spa

如圖,存儲字符串是將字符串二進制數組的形式存儲在 redis 中,位圖能夠直接對 二進制的數組操做,位圖的優點在於能夠用 0 和 1來存儲布爾值,這大大下降了咱們的存儲空間消耗。因爲這個特性,咱們用位圖來記錄簽到信息,記錄活躍用戶等,能夠達到節省空間的能力(後面會有介紹)。code

那咱們如何對二進制的數組進行操做呢?orm

基本存取

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

最後

上述內容對你們有所幫助的話,請幫我 點個贊👍,創做不易,感謝支持!

若是本文有任何錯誤,感謝各位批評指教 !

相關文章
相關標籤/搜索