最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis統(tǒng)計獨立用戶訪問量的四種方案

 更新時間:2026年04月16日 08:39:11   作者:身如柳絮隨風(fēng)揚  
Redis 提供了多種數(shù)據(jù)結(jié)構(gòu)來高效實現(xiàn) UV 統(tǒng)計,各有優(yōu)劣,本文將詳細(xì)對比 Set、Bitmap、HyperLogLog、incr + 日期維度(即用戶提到的兩種方式)四種方案,并通過流程圖和代碼示例幫助你選型,需要的朋友可以參考下

在網(wǎng)站分析、廣告監(jiān)測、推薦系統(tǒng)等場景中,獨立用戶訪問量(UV,Unique Visitor) 是一個核心指標(biāo)。UV 的關(guān)鍵在于去重——同一個用戶多次訪問只計一次。

Redis 提供了多種數(shù)據(jù)結(jié)構(gòu)來高效實現(xiàn) UV 統(tǒng)計,各有優(yōu)劣。本文將詳細(xì)對比 Set、Bitmap、HyperLogLog、incr + 日期維度(即用戶提到的兩種方式)四種方案,并通過流程圖和代碼示例幫助你選型。

一、方案概覽(附選型流程圖)

二、方案一:Set 集合(精確去重)

最直觀的方法:每個統(tǒng)計周期(如一天)維護(hù)一個 Set,將每個訪問過的用戶 ID 加入 Set,最后用 SCARD 獲取基數(shù)。

# 示例:用戶 1001 訪問首頁
redis.sadd("uv:home:2025-04-15", "user_1001")
# 獲取當(dāng)天 UV
uv = redis.scard("uv:home:2025-04-15")

優(yōu)點:精確、支持用戶 ID 任意類型(字符串/整數(shù))。
缺點:內(nèi)存占用高,每個用戶 ID 都需要存儲一份(例如 1000 萬用戶,每個 ID 按 30 字節(jié)算,需約 300MB)。
適用:用戶量?。?lt; 百萬級)或必須精確統(tǒng)計的場景。

三、方案二:Bitmap(位圖法,精確且內(nèi)存極?。?/h2>

當(dāng)用戶 ID 是整數(shù)且相對連續(xù)(如自增 user_id)時,可以用 Bitmap 將每個 user_id 映射到位偏移量,存在則置 1。

# 用戶 ID=1001 訪問,設(shè)置第 1001 位為 1
redis.setbit("uv:home:2025-04-15", 1001, 1)
# 統(tǒng)計當(dāng)日 UV(統(tǒng)計 1 的個數(shù))
uv = redis.bitcount("uv:home:2025-04-15")

內(nèi)存計算:如果有 1 億用戶,只需 1億 bit ≈ 12 MB,比 Set 節(jié)省數(shù)十倍。
優(yōu)點:精確、內(nèi)存極小、性能高(bitcount 時間復(fù)雜度 O(n) 但 Redis 做了優(yōu)化)。
缺點:用戶 ID 必須為整數(shù)且不太稀疏(若 ID 最大為 10 億,但實際只有 100 萬用戶,依然會占用 125MB 的連續(xù)空間,造成浪費)。
適用:用戶 ID 是自增整數(shù)、最大 ID 可控(如 2^32 以內(nèi))、對內(nèi)存敏感且要求精確的場景。

四、方案三:HyperLogLog(近似去重,誤差 0.81%)

你提到的 HyperLogLog 是一種概率性數(shù)據(jù)結(jié)構(gòu),用 12KB 固定內(nèi)存即可統(tǒng)計上億級別的 UV,誤差率約為 0.81%。

# 添加元素
redis.pfadd("uv:home:2025-04-15", "user_1001", "user_1002")
# 獲取近似 UV
uv = redis.pfcount("uv:home:2025-04-15")

原理:通過哈希函數(shù)將元素映射為二進(jìn)制串,觀察低位連續(xù)零的個數(shù)來估計基數(shù)。
優(yōu)點:內(nèi)存固定(12KB),性能極高(O(1) 添加),適合海量數(shù)據(jù)。
缺點:不精確(誤差 ±0.81%),無法取出具體有哪些用戶(只能計數(shù)),不適合敏感計費場景。
適用:大屏展示、趨勢分析、非精準(zhǔn)營銷統(tǒng)計等可容忍誤差的場景。

五、方案四:incr + 日期維度(你提到的“incr自增”)

嚴(yán)格來說,單純使用 INCR 無法實現(xiàn)獨立用戶去重,因為 INCR 是累加計數(shù)器,每次訪問都 +1,得到的是 PV(頁面訪問量),不是 UV。

# 這樣得到的是 PV,不是 UV
redis.incr("pv:home:2025-04-15")

如何用 incr 輔助 UV?
通常做法是 incr + Set/Bitmap/HLL 組合

  • 用 Set 或 HLL 存儲獨立用戶(保證去重)
  • 同時用 incr 記錄總訪問次數(shù)(PV)
# 記錄 PV
redis.incr("pv:home:2025-04-15")
# 記錄 UV(使用 HLL)
redis.pfadd("uv:home:2025-04-15", user_id)

所以,你提到的“incr 通過自增方式判斷用戶的訪問量”并不適用于 UV,應(yīng)理解為 PV 統(tǒng)計。但為了貼合你的原文,我們修正說明:incr 適合 PV,UV 必須依賴去重結(jié)構(gòu)。

六、四種方案對比表

方案內(nèi)存占用精確性支持用戶ID類型時間復(fù)雜度(寫入)典型應(yīng)用
SetO(N)(每個元素完整存儲)精確任意O(1)小規(guī)模精確統(tǒng)計
BitmapO(max_id) 位,連續(xù)整數(shù)時極省精確非負(fù)整數(shù)O(1)億級整數(shù)ID,如手機號后幾位
HyperLogLog固定 12KB近似(誤差 0.81%)任意(需哈希)O(1)海量UV快速估算
incr(PV)固定(每個key一個整數(shù))精確無(只是計數(shù))O(1)頁面訪問總量(非UV)

七、實戰(zhàn)選型建議

你的用戶 ID 是整數(shù)且密集(如 user_id 從 1 到 5000 萬)
?? 首選 Bitmap,精確且內(nèi)存最小。

用戶 ID 是字符串(如 UUID、手機號),且允許 0.81% 誤差
?? 首選 HyperLogLog,12KB 內(nèi)存統(tǒng)計上億 UV。

必須精確統(tǒng)計,且用戶量較?。?lt; 500 萬)
?? 用 Set,簡單可靠。

既要 PV 又要 UV
?? 組合:INCR 記錄 PV + PFADD 記錄 UV(HLL)或 SADD(Set)。

數(shù)據(jù)敏感場景(如計費、反 作弊)
? 不能用 HyperLogLog,必須用 Bitmap 或 Set。

八、代碼示例:三種方案對比(Python + Redis)

import redis
r = redis.Redis(decode_responses=True)

# 模擬 100 萬個用戶 ID(字符串)
user_ids = [f"user_{i}" for i in range(1_000_000)]

# 1. Set 方式
key_set = "uv:set"
r.delete(key_set)
for uid in user_ids:
    r.sadd(key_set, uid)
print(f"Set 精確 UV: {r.scard(key_set)}")
print(f"Set 內(nèi)存: {r.memory_usage(key_set) / 1024 / 1024:.2f} MB")

# 2. HyperLogLog 方式
key_hll = "uv:hll"
r.delete(key_hll)
for uid in user_ids:
    r.pfadd(key_hll, uid)
print(f"HLL 近似 UV: {r.pfcount(key_hll)}")
print(f"HLL 內(nèi)存: {r.memory_usage(key_hll)} 字節(jié)")  # 固定約 12KB

# 3. Bitmap 方式(假設(shè) user_id 轉(zhuǎn)為整數(shù),此處用 i 模擬)
key_bit = "uv:bitmap"
r.delete(key_bit)
for i in range(1, 1_000_001):
    r.setbit(key_bit, i, 1)
print(f"Bitmap 精確 UV: {r.bitcount(key_bit)}")
print(f"Bitmap 內(nèi)存: {r.memory_usage(key_bit) / 1024 / 1024:.2f} MB")

運行結(jié)果參考(百萬級):

  • Set:內(nèi)存約 30~40 MB
  • HLL:12 KB
  • Bitmap:0.12 MB(100 萬 bit = 0.125 MB)

九、總結(jié)

你的原始說法修正/補充
“incr 通過自增方式判斷用戶的訪問量”incr 得到的是 PV(總訪問次數(shù)),不是 UV。UV 需要去重。
“HyperLogLog 用來做基數(shù)統(tǒng)計,誤差很小,不適合數(shù)據(jù)敏感場景”? 正確。誤差約 0.81%,內(nèi)存固定 12KB,適合海量近似統(tǒng)計。

最終結(jié)論

  • 對精度要求不高、數(shù)據(jù)量極大 → HyperLogLog
  • 需要精確、用戶 ID 為整數(shù) → Bitmap
  • 需要精確、用戶 ID 為字符串且量小 → Set
  • 想要統(tǒng)計 PV → incr

合理選擇數(shù)據(jù)結(jié)構(gòu),能讓你的 UV 統(tǒng)計既快又省內(nèi)存。

以上就是Redis統(tǒng)計獨立用戶訪問量的四種方案的詳細(xì)內(nèi)容,更多關(guān)于Redis統(tǒng)計獨立用戶訪問量的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 深入剖析 Redis 的三種集群方式以及實戰(zhàn)配置

    深入剖析 Redis 的三種集群方式以及實戰(zhàn)配置

    本文深入解析Redis三種集群部署方式,文章包含完整的配置示例和操作指南,為Redis集群部署提供實用參考,感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • Redis如何清理過期的key以及對應(yīng)的解決方法分析

    Redis如何清理過期的key以及對應(yīng)的解決方法分析

    這篇文章主要介紹了Redis如何清理過期的key以及對應(yīng)的解決方法的相關(guān)資料,Redis提供了多種過期刪除策略和內(nèi)存淘汰策略,以管理緩存和臨時數(shù)據(jù),需要的朋友可以參考下
    2025-03-03
  • 關(guān)于Redis你可能不了解的一些事

    關(guān)于Redis你可能不了解的一些事

    這篇文章主要給大家介紹了關(guān)于Redis你可能不了解的一些事,對大家學(xué)習(xí)或者使用Redis具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • 詳解Redis復(fù)制原理

    詳解Redis復(fù)制原理

    與大多數(shù)db一樣,Redis也提供了復(fù)制機制,以滿足故障恢復(fù)和負(fù)載均衡等需求。復(fù)制也是Redis高可用的基礎(chǔ),哨兵和集群都是建立在復(fù)制基礎(chǔ)上實現(xiàn)高可用的。復(fù)制不僅提高了整個系統(tǒng)的容錯能力,還可以水平擴展,通過增加多個Redis只讀從實例來減輕主實例的壓力。
    2021-06-06
  • 解析Redis Cluster原理

    解析Redis Cluster原理

    redis最開始使用主從模式做集群,若master宕機需要手動配置slave轉(zhuǎn)為master;后來為了高可用提出來哨兵模式,該模式下有一個哨兵監(jiān)視master和slave,若master宕機可自動將slave轉(zhuǎn)為master,但它也有一個問題,就是不能動態(tài)擴充;所以在3.x提出cluster集群模式
    2021-06-06
  • Redis主從復(fù)制作用及搭建過程

    Redis主從復(fù)制作用及搭建過程

    Redis?的主從復(fù)制是實現(xiàn)數(shù)據(jù)備份、讀寫分離和水平擴展的核心機制之一,通過主從復(fù)制,一個主節(jié)點(Master)可以將數(shù)據(jù)同步到多個從節(jié)點(Slave),從節(jié)點還可以級聯(lián)創(chuàng)建自己的從節(jié)點,從而形成樹狀結(jié)構(gòu),本文給大家介紹Redis主從復(fù)制的相關(guān)知識,感興趣的朋友一起看看吧
    2025-06-06
  • redis數(shù)據(jù)類型_動力節(jié)點Java學(xué)院整理

    redis數(shù)據(jù)類型_動力節(jié)點Java學(xué)院整理

    這篇文章主要介紹了redis數(shù)據(jù)類型,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08
  • redis?setIfAbsent返回null的問題及解決

    redis?setIfAbsent返回null的問題及解決

    這篇文章主要介紹了redis?setIfAbsent返回null的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • 為何Redis使用跳表而非紅黑樹實現(xiàn)SortedSet

    為何Redis使用跳表而非紅黑樹實現(xiàn)SortedSet

    本篇文章主要介紹了為何Redis使用跳表而非紅黑樹實現(xiàn)SortedSet,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Redis實現(xiàn)事物以及鎖的方法

    Redis實現(xiàn)事物以及鎖的方法

    本文主要介紹了Redis實現(xiàn)事物以及鎖的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07

最新評論

六枝特区| 马公市| 榆树市| 上高县| 搜索| 基隆市| 阿拉善盟| 屏东县| 兰溪市| 冕宁县| 武夷山市| 神木县| 峨眉山市| 乐陵市| 太原市| 贵定县| 徐水县| 江都市| 锡林浩特市| 会泽县| 阿克陶县| 大新县| 元江| 莫力| 安达市| 延安市| 韶山市| 招远市| 德阳市| 苍南县| 潞城市| 清原| 怀宁县| 宝坻区| 泸州市| 淮北市| 浑源县| 临颍县| 西乌| 土默特右旗| 睢宁县|