前言
在工作中我們經(jīng)常遇到這樣的需求,要對某個(gè)在線網(wǎng)站的活躍用戶數(shù)量進(jìn)行統(tǒng)計(jì)。這里我們以redis為例,說明一下其實(shí)現(xiàn)的過程。
實(shí)現(xiàn)方法
在Redis中存在bitmap這種數(shù)據(jù)類型,這種數(shù)據(jù)類型是建立在string數(shù)據(jù)類型之上的。這里,我們主要用到setbit、bitcount這2個(gè)命令,而使用的客戶端為python的redis庫。
import redis
r = redis.StrictRedis(host="127.0.0.1",port=6379,db=0)
這里我們引入redis庫,然后實(shí)例化了1個(gè)StrictRedis類。由于這里使用的默認(rèn)的選項(xiàng),我們可以在StrictRedis不傳入任何參數(shù)。
這里我們定義3個(gè)方法storeDailyVisit,removeDailyVisit和countVisits,分別用于用戶上線時(shí)進(jìn)行記錄、用戶下線時(shí)進(jìn)行記錄以及查看指定日期活躍的用戶總數(shù)。
下面我們來看storeDailyVisit函數(shù):
def storeDailyVisit(date,userId,verbose=False):
key = "visits:daily:"+date
r.setbit(key,userId,1)
if verbose:
print("User",userId,"visited on",date)
該函數(shù)接收2個(gè)參數(shù)date和userId,分別為指定的日期和用戶的ID,第3個(gè)參數(shù)用于指定是否輸出內(nèi)容。在這里我們輸出用戶訪問的信息,當(dāng)然我們可以將其記錄在日志中等其他操作。
當(dāng)某個(gè)用戶登錄后,我們調(diào)用該函數(shù),傳入今天的日期及用戶的ID。removeDailyVisit函數(shù)與storeDailyVisit函數(shù)類似,它主要負(fù)責(zé)當(dāng)用戶退出當(dāng)前網(wǎng)站時(shí)將其從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函數(shù)得到當(dāng)前活躍的用戶的數(shù)量:
def countVisits(date):
key = "visits:daily:"+date
return r.bitcount(key)
這里,countVisits函數(shù)接收1個(gè)日期的參數(shù),它通過調(diào)用bitmaps數(shù)據(jù)類型的bitcount函數(shù)得到當(dāng)前數(shù)字為1的個(gè)數(shù)。這里我們將它返回給調(diào)用者。
由于bitmaps是1種按位進(jìn)行操作的數(shù)據(jù)類型,其是1串連續(xù)的二進(jìn)制數(shù)字(0或1)。我們通過對其某個(gè)位上的數(shù)值進(jìn)行設(shè)置為1,然后通過bitcount函數(shù)統(tǒng)計(jì)這串二進(jìn)制數(shù)字上為1的總數(shù),從而得到當(dāng)前活躍的用戶總數(shù)。
另外,我們還可以使用redis的set數(shù)據(jù)類型來實(shí)現(xiàn)同樣的操作,我們可以通過下表來查看這二者的差別:
| 數(shù)據(jù)類型 | 每個(gè)消耗的位 | 存儲(chǔ)用戶 | 消耗的內(nèi)存 |
|———-|—————|————|——————|
| bitmap | 1bit | 500000000 |1*500000000B=59.6Mb|
| set | 32bit | 500000000 |32*500000000B=1.91Tb|
我們可以清楚的看到,當(dāng)存儲(chǔ)的用戶為5個(gè)億的時(shí)候,需要消耗的內(nèi)存bitmap為59.6MB,而set為1.91TB,整整32倍。因此,在實(shí)際的在線網(wǎng)站中,我們更多使用的是bitmaps統(tǒng)計(jì)在線用戶的數(shù)量。
參考文章:http://redis.io/topics/data-types-intro#bitmaps
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作能帶來一定的幫助,如果有疑問大家可以留言交流。
您可能感興趣的文章:- PHP+Redis 消息隊(duì)列 實(shí)現(xiàn)高并發(fā)下注冊人數(shù)統(tǒng)計(jì)的實(shí)例
- PHP使用redis實(shí)現(xiàn)統(tǒng)計(jì)緩存mysql壓力的方法
- Redis中統(tǒng)計(jì)各種數(shù)據(jù)大小的方法
- 基于redis實(shí)現(xiàn)token驗(yàn)證用戶是否登陸
- redis 實(shí)現(xiàn)登陸次數(shù)限制的思路詳解
- redis開啟和禁用登陸密碼校驗(yàn)的方法
- 基于Redis位圖實(shí)現(xiàn)系統(tǒng)用戶登錄統(tǒng)計(jì)