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

Redis統(tǒng)計(jì)獨(dú)立用戶訪問(wèn)量的四種方案

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

六、四種方案對(duì)比表

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

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

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

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

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

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

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

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

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

# 模擬 100 萬(wàn)個(gè)用戶 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")

運(yùn)行結(jié)果參考(百萬(wàn)級(jí)):

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

九、總結(jié)

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

最終結(jié)論

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

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

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

相關(guān)文章

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

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

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

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

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

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

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

    詳解Redis復(fù)制原理

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

    解析Redis Cluster原理

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

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

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

    redis數(shù)據(jù)類型_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

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

    redis?setIfAbsent返回null的問(wèn)題及解決

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

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

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

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

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

最新評(píng)論

皮山县| 德兴市| 中阳县| 南丹县| 额尔古纳市| 米脂县| 来安县| 福贡县| 大丰市| 克什克腾旗| 扶余县| 沛县| 化德县| 山西省| 教育| 肃北| 衡阳市| 广昌县| 青冈县| 瑞昌市| 涿州市| 英德市| 石城县| 康保县| 湘潭县| 北川| 宾川县| 莆田市| 漾濞| 双桥区| 博客| 邓州市| 昔阳县| 乐业县| 禄劝| 都昌县| 兴业县| 连山| 桐柏县| 成都市| 阜新|