Redis統(tǒng)計訪問量的3種實現(xiàn)方式
一、你是否遇到過這些統(tǒng)計難題?
- 高并發(fā)場景下內(nèi)存爆炸:用Hash統(tǒng)計日活時,單鍵內(nèi)存占用飆升到10MB?
- 獨立訪客重復(fù)計數(shù):用戶多次訪問被重復(fù)統(tǒng)計,導(dǎo)致UV數(shù)據(jù)虛高?
- 近似值誤差過大:百萬級PV統(tǒng)計時,誤差率超過5%?
這些問題,Redis的3種核心方案能幫你解決!
二、方案一:Hash結(jié)構(gòu)實時統(tǒng)計
適用場景:
- 實時統(tǒng)計獨立用戶(如日活/周活)
- 需要精確計數(shù)(如商品點擊次數(shù))
核心代碼:
# 場景:記錄用戶訪問時間戳(防重復(fù)計數(shù)) pipeline.hset("user:visits:202310", user_id, time.time()) pipeline.expire("user:visits:202310", 86400) # 每天清理一次 # 統(tǒng)計當(dāng)前活躍用戶數(shù) current_uv = redis.hlen("user:visits:202310")
參數(shù)說明:
hset
:哈希表存儲用戶ID和最后訪問時間expire
:自動清理過期數(shù)據(jù),避免內(nèi)存泄漏- 痛點解決:通過時間戳去重,精確統(tǒng)計獨立用戶
內(nèi)存優(yōu)化技巧:
- 問題:10萬用戶ID存儲需約
100KB * 10^5 = 10GB
- 方案:使用
user_id:md5
縮短鍵名,內(nèi)存占用可降低至**<1MB/萬用戶**
三、方案二:BitMap統(tǒng)計獨立訪客
適用場景:
- 億級用戶規(guī)模的UV統(tǒng)計
- 內(nèi)存敏感場景(如單機統(tǒng)計全站訪問量)
核心代碼:
# 場景:統(tǒng)計本月訪問過的用戶(假設(shè)用戶ID為整數(shù)) user_id = 123456 redis.setbit("uv:202310", user_id, 1) # 獲取本月UV總數(shù) total_uv = redis.bitcount("uv:202310")
參數(shù)說明:
setbit
:將用戶ID對應(yīng)位設(shè)為1,每個用戶僅占1bit內(nèi)存bitcount
:統(tǒng)計所有置位位數(shù),時間復(fù)雜度O(1)
內(nèi)存對比:
方法 | 100萬用戶內(nèi)存占用 | 精度 |
---|---|---|
Hash | ~100MB | 100% |
BitMap | ~125KB | 100% |
四、方案三:HyperLogLog估算UV
適用場景:
- 超大規(guī)模近似統(tǒng)計(如全網(wǎng)日活)
- 可接受誤差的場景(誤差率<0.8%)
核心代碼:
# 場景:統(tǒng)計全站日活(誤差率0.5%) redis.pfadd("uv:202310", user_id) estimated_uv = redis.pfcount("uv:202310")
參數(shù)說明:
pfadd
:將用戶ID加入HyperLogLog結(jié)構(gòu)pfcount
:返回近似值,內(nèi)存占用僅<1KB/百萬用戶
性能對比:
方法 | 1000萬用戶內(nèi)存 | 統(tǒng)計誤差 |
---|---|---|
BitMap | 1.25MB | 0% |
HyperLogLog | <1KB | 0.5% |
五、實戰(zhàn)選擇指南
對比表格:
方案 | 內(nèi)存占用 | 精度 | 適用場景 |
---|---|---|---|
Hash | 中(MB級) | 100% | 小規(guī)模精確統(tǒng)計 |
BitMap | 極低(KB級) | 100% | 大規(guī)模精確去重 |
HyperLogLog | 超低(KB級) | <1% | 超大規(guī)模近似統(tǒng)計 |
優(yōu)化建議:
- 混合方案:用Hash統(tǒng)計小時級數(shù)據(jù),用HyperLogLog匯總?cè)占墧?shù)據(jù)
- 數(shù)據(jù)分片:對億級用戶ID按user_id % N分片存儲,降低單鍵內(nèi)存壓力
- 冷熱分離:歷史數(shù)據(jù)定期轉(zhuǎn)儲到MySQL,Redis僅保留活躍數(shù)據(jù)
六、總結(jié)
Redis統(tǒng)計訪問量的本質(zhì)是內(nèi)存優(yōu)化+算法選型的平衡。
- 痛點場景:用BitMap解決內(nèi)存爆炸,用HyperLogLog應(yīng)對超大規(guī)模
- 實時需求:Hash結(jié)構(gòu)仍是精確統(tǒng)計的首選
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Redis Template實現(xiàn)分布式鎖的實例代碼
使用Redis的SETNX命令獲取分布式鎖的步驟,接下來通過本文給大家介紹Redis Template實現(xiàn)分布式鎖的實例代碼,代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧2018-09-09CentOS7.5使用mysql_multi方式安裝MySQL5.7.28多實例(詳解)
這篇文章主要介紹了CentOS7.5使用mysql_multi方式安裝MySQL5.7.28多實例,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2020-01-01