你們有沒有想過如何統計活躍用戶數量?若是是本身作,那該怎麼作?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
請對照上圖,咱們一塊兒完成下面的探究:以字符串存儲,能夠經過 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
複製代碼
結論:能夠的
以字符串存儲,能夠經過 settbit
修改值嗎?
咱們能夠試着將 offset 7 對應的 value 改爲 1, 若是成功了,h 字符應該變成 i
> setbit str 7 1
(integer) 0
> get str
"ii"
複製代碼
結論:能夠
用 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 個應用場景:
我在這裏稍微介紹一下思路,而後附上一個 統計活躍用戶的數量 可供參考
統計活躍用戶的數量
login:2020-3
offset
, 如 id
對應二進制數組的下標,id
爲 int
setbit
將對應的offset
設置成 1bitcount
統計某個行爲和時間範圍的活躍人數,如 bitcount login:2020-3
Demo: DailyActiveUsers
獲取第一次簽到和第一次未簽到的時間
login:2020-3:Tom
offset
, 如 1號對應二進制數組的下標 0, 2 號爲 1setbit
將對應的offset
設置成 1bitpos
統計某個行爲和時間範圍和對象的簽到狀況,如 bitpos login:2020-3:Tom 1
上述內容對你們有所幫助的話,請幫我 點個贊👍,創做不易,感謝支持!
若是本文有任何錯誤,感謝各位批評指教 !