前言
在工作中我們經常遇到這樣的需求,要對某個在線網站的活躍用戶數量進行統計。這裡我們以redis為例,說明一下其實現的過程。
實現方法
在Redis中存在bitmap這種數據類型,這種數據類型是建立在string數據類型之上的。這裡,我們主要用到setbit、bitcount這2個命令,而使用的客戶端為python的redis庫。
import redis r = redis.StrictRedis(host="127.0.0.1",port=6379,db=0)
這裡我們引入redis庫,然後實例化了1個StrictRedis類。由於這裡使用的默認的選項,我們可以在StrictRedis不傳入任何參數。
r = redis.StrictRedis()
這裡我們定義3個方法storeDailyVisit,removeDailyVisit和countVisits,分別用於用戶上線時進行記錄、用戶下線時進行記錄以及查看指定日期活躍的用戶總數。
下面我們來看storeDailyVisit函數:
def storeDailyVisit(date,userId,verbose=False): key = "visits:daily:"+date r.setbit(key,userId,1) if verbose: print("User",userId,"visited on",date)
該函數接收2個參數date和userId,分別為指定的日期和用戶的ID,第3個參數用於指定是否輸出內容。在這裡我們輸出用戶訪問的信息,當然我們可以將其記錄在日志中等其他操作。
當某個用戶登錄後,我們調用該函數,傳入今天的日期及用戶的ID。removeDailyVisit函數與storeDailyVisit函數類似,它主要負責當用戶退出當前網站時將其從bitmap表中移除。
def removeDailyVisit(date,userId,verbose=False): key = "visits:daily:"+date r.setbit(key,userId,0) if verbose: print("User",userId,"leave on",date)
下面我們通過countVisits函數得到當前活躍的用戶的數量:
def countVisits(date): key = "visits:daily:"+date return r.bitcount(key)
這裡,countVisits函數接收1個日期的參數,它通過調用bitmaps數據類型的bitcount函數得到當前數字為1的個數。這裡我們將它返回給調用者。
由於bitmaps是1種按位進行操作的數據類型,其是1串連續的二進制數字(0或1)。我們通過對其某個位上的數值進行設置為1,然後通過bitcount函數統計這串二進制數字上為1的總數,從而得到當前活躍的用戶總數。
另外,我們還可以使用redis的set數據類型來實現同樣的操作,我們可以通過下表來查看這二者的差別:
| 數據類型 | 每個消耗的位 | 存儲用戶 | 消耗的內存 | |———-|—————|————|——————| | bitmap | 1bit | 500000000 |1*500000000B=59.6Mb| | set | 32bit | 500000000 |32*500000000B=1.91Tb|
我們可以清楚的看到,當存儲的用戶為5個億的時候,需要消耗的內存bitmap為59.6MB,而set為1.91TB,整整32倍。因此,在實際的在線網站中,我們更多使用的是bitmaps統計在線用戶的數量。
參考文章:http://redis.io/topics/data-types-intro#bitmaps
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。