Redis容許使用二進制數據的Key(binary keys) 和二進制數據的Value(binary values)。Bitmap就是二進制數據的value。Redis的 setbit(key, offset, value)操做對指定的key的value的指定偏移(offset)的位置1或0,時間複雜度是O(1)。php
Redis BitMaps的操做命令:mysql
SETBIT key offset value linux
對指定的key的value的指定偏移(offset)的位置1或0web
GETBIT key offsetredis
獲取offset設置的值,未設置過默認返回0sql
BITCOUNT key [start end] 網站
統計指定key位置爲1的數量(區間統計不建議使用,bitcount用的是byte來計算位數,其餘setbit和getbit用的是bit,詳見:http://blog.linuxphp.org/archives/1627/)ui
BITOP operation destkey key [key ...]spa
Bit運算,BITOP 支持四種表達式運算: AND(交集), OR(並集), XOR(異或) 和NOT(取非), 用法以下:
BITOP AND destkey srckey1 srckey2 srckey3 ... srckeyN
BITOP OR destkey srckey1 srckey2 srckey3 ... srckeyN
BITOP XOR destkey srckey1 srckey2 srckey3 ... srckeyN
BITOP NOT destkey srckey日誌
BITPOS key bit [start] [end]
返回設置爲1或0的一個字符串中的第一個點的位置
活躍用戶統計
活躍用戶是項目中常常須要統計的一個項目,咱們以前的作法是:
直接從用戶的登陸日誌中計算提取 (須要腳本定時計算,比較耗時)
將天天的登陸用戶的uid存在Redis的SET結構中 (用戶基數大的狀況下,開銷大)
以上作法當然沒有什麼問題,可是當用戶規模特別大的時候,就顯得笨拙或者開銷比較大,因而Redis bitmaps就上場了。
爲統計某一天的用戶登錄數量,首先以當天的日誌加固定的前綴做爲key,創建一個bitmap。例如:userlogin:2016-01-15,每一位二進制的位作爲一個用戶ID的標識(offset)。當用戶訪問時,就把bitmap中標識此用戶的二進制(value)從0置爲1。
用戶登陸時執行一次SETBIT(key, userId, 1),將bitmap中對應位置的位置爲1。當統計某一天用戶活躍數時,直接bitcount那天對應的key,固然還能夠用bitop計算出如最近7天,一月個的用戶活躍數。代碼以下:
2. 用戶行爲統計
網站通常常常有個場景就是,判斷用戶是否操做過某個動做,好比是否點擊過某個按鈕(根據是否點擊改變按鈕顏色),是否領取過優惠券(是否領取過展現邏輯不一樣)。
這些場景其實也能夠運用到bitMap,可是前提是不大關注行爲的人,由於bitMap並不能計算出用戶的uid。
之因此選擇用bitmap,就是由於bitmap的操做很是快,並且也比較節省資源。
擴展下,其實如點贊喜歡的判斷邏輯也能夠用bitmap來實現,固然關係邏輯仍是存在mysql中(由於這些關係有時候很重要),用bitmap來加速判斷邏輯。
最後,說一下bitmap的兩個容易採坑的地方:
第一個,就是bitcount命令,在使用start,end的時候必定要注意,setbit和getbit命令操做的是bit,可是bitcount用的是byte來計算位數,二者差了8倍,所以這點很容易採坑,也不建議用。
setbit的offset是用大小限制的,在0到 232(最大使用512M內存)之間,即0~4294967296以前,超過這個數會自動將offset轉化爲0,所以使用的時候必定要注意。
參考: