偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

如何用Redis統(tǒng)計海量UV?

存儲 存儲軟件 Redis
我們先思考一個常見的業(yè)務(wù)問題:如果你負(fù)責(zé)開發(fā)維護(hù)一個大型的網(wǎng)站,有一天老板找產(chǎn)品經(jīng)理要網(wǎng)站每個網(wǎng)頁每天的 UV 數(shù)據(jù),然后讓你來開發(fā)這個統(tǒng)計模塊,你會如何實現(xiàn)?

[[416080]]

前言

我們先思考一個常見的業(yè)務(wù)問題:如果你負(fù)責(zé)開發(fā)維護(hù)一個大型的網(wǎng)站,有一天老板找產(chǎn)品經(jīng)理要網(wǎng)站每個網(wǎng)頁每天的 UV 數(shù)據(jù),然后讓你來開發(fā)這個統(tǒng)計模塊,你會如何實現(xiàn)?

統(tǒng)計uv的常用方法以及優(yōu)缺點

其實要是單純的統(tǒng)計pv是比較好辦的,直接用redis的incr就行,但是uv的話,它要去重,同一個用戶一天之內(nèi)的多次訪問請求只能計數(shù)一次。這就要求每一個網(wǎng)頁請求都需要帶上用戶的 ID,無論是登陸用戶還是未登陸用戶都需要一個唯一 ID 來標(biāo)識。

set

比較容易想到的是為每一個頁面一個獨(dú)立的 set 集合來存儲所有當(dāng)天訪問過此頁面的用戶 ID。當(dāng)一個請求過來時,我們使用 sadd 將用戶 ID 塞進(jìn)去就可以了。通過 scard 可以取出這個集合的大小,這個數(shù)字就是這個頁面的 UV 數(shù)據(jù)。沒錯,這是一個非常簡單的方案。

但是,如果你的頁面訪問量非常大,比如一個爆款頁面幾千萬的 UV,你需要一個很大的 set 集合來統(tǒng)計,這就非常浪費(fèi)空間。如果這樣的頁面很多,那所需要的存儲空間是驚人的。

hash

hash和set在處理uv的問題上其實類似,把用戶id作為hash的key的確可以去重,但是如果訪問量大了之后也會消耗很大的內(nèi)存空間

bitmap

bitmap同樣是一種可以統(tǒng)計基數(shù)的方法,可以理解為用bit數(shù)組存儲元素,例如01101001,表示的是[1,2,4,8],bitmap中1的個數(shù)就是基數(shù)。bitmap也可以輕松合并多個集合,只需要將多個數(shù)組進(jìn)行異或操作就可以了。bitmap相比于Set,Hash也大大節(jié)省了內(nèi)存,我們來粗略計算一下,統(tǒng)計1億個數(shù)據(jù)的基數(shù),需要的內(nèi)存是:100000000/8/1024/1024 ≈ 12M。

雖然bitmap在節(jié)省空間方面已經(jīng)有了不錯的表現(xiàn),但是如果需要統(tǒng)計1000個對象,就需要大約12G的內(nèi)存,顯然這個結(jié)果仍然不能令我們滿意。在這種情況下,HyperLogLog將會出來拯救我們。

HyperLogLog

這就是本節(jié)要引入的一個解決方案,Redis 提供了 HyperLogLog 數(shù)據(jù)結(jié)構(gòu)就是用來解決這種統(tǒng)計問題的。HyperLogLog 提供不精確的去重計數(shù)方案,雖然不精確但是也不是非常不精確,標(biāo)準(zhǔn)誤差是 0.81%,這樣的精確度已經(jīng)可以滿足上面的 UV 統(tǒng)計需求了。

HyperLogLog 數(shù)據(jù)結(jié)構(gòu)是 Redis 的高級數(shù)據(jù)結(jié)構(gòu),它非常有用,但是令人感到意外的是,使用過它的人非常少。

使用方法

Redis 的位數(shù)組是自動擴(kuò)展,如果設(shè)置了某個偏移位置超出了現(xiàn)有的內(nèi)容范圍,就會自動將位數(shù)組進(jìn)行零擴(kuò)充。

命令

HyperLogLog 提供了兩個指令 pfadd 和 pfcount,根據(jù)字面意義很好理解,一個是增加計數(shù),一個是獲取計數(shù)。

具體實現(xiàn)

pfadd 用法和 set 集合的 sadd 是一樣的,來一個用戶 ID,就將用戶 ID 塞進(jìn)去就是。pfcount 和 scard 用法是一樣的,直接獲取計數(shù)值。關(guān)鍵是它非常省空間,載統(tǒng)計海量uv的時候,只占用了12k的空間

  1. 127.0.0.1:6379> pfadd codehole user1 
  2. (integer) 1 
  3. 127.0.0.1:6379> pfcount codehole 
  4. (integer) 1 
  5. 127.0.0.1:6379> pfadd codehole user2 
  6. (integer) 1 
  7. 127.0.0.1:6379> pfcount codehole 
  8. (integer) 2 
  9. 127.0.0.1:6379> pfadd codehole user3 
  10. (integer) 1 
  11. 127.0.0.1:6379> pfcount codehole 
  12. (integer) 3 
  13. 127.0.0.1:6379> pfadd codehole user4 
  14. (integer) 1 
  15. 127.0.0.1:6379> pfcount codehole 
  16. (integer) 4 
  17. 127.0.0.1:6379> pfadd codehole user5 
  18. (integer) 1 
  19. 127.0.0.1:6379> pfcount codehole 
  20. (integer) 5 
  21. 127.0.0.1:6379> pfadd codehole user6 
  22. (integer) 1 
  23. 127.0.0.1:6379> pfcount codehole 
  24. (integer) 6 
  25. 127.0.0.1:6379> pfadd codehole user7 user8 user9 user10 
  26. (integer) 1 
  27. 127.0.0.1:6379> pfcount codehole 
  28. (integer) 10 

簡單試了一下,發(fā)現(xiàn)還蠻精確的,一個沒多也一個沒少。接下來我們使用腳本,往里面灌更多的數(shù)據(jù),看看它是否還可以繼續(xù)精確下去,如果不能精確,差距有多大。

我們將數(shù)據(jù)增加到 10w 個,看看總量差距有多大。

  1. public class JedisTest { 
  2.   public static void main(String[] args) { 
  3.     Jedis jedis = new Jedis(); 
  4.     for (int i = 0; i < 100000; i++) { 
  5.       jedis.pfadd("codehole""user" + i); 
  6.     } 
  7.     long total = jedis.pfcount("codehole"); 
  8.     System.out.printf("%d %d\n", 100000, total); 
  9.     jedis.close(); 
  10.   } 

跑了約半分鐘,我們看輸出:

  1. > python pftest.py 
  2. 100000 99723 

差了 277 個,按百分比是 0.277%,對于上面的 UV 統(tǒng)計需求來說,誤差率也不算高。然后我們把上面的腳本再跑一邊,也就相當(dāng)于將數(shù)據(jù)重復(fù)加入一邊,查看輸出,可以發(fā)現(xiàn),pfcount 的結(jié)果沒有任何改變,還是 99723,說明它確實具備去重功能。

責(zé)任編輯:武曉燕 來源: 程序員小飯
相關(guān)推薦

2025-03-05 08:40:00

RedisJava開發(fā)

2019-12-06 15:20:58

Redis獨(dú)立用戶數(shù)據(jù)庫

2019-10-17 09:25:56

Spark StreaPVUV

2019-08-01 15:08:37

PythonLine操作系統(tǒng)

2021-05-24 08:58:34

Redis Bitmap 數(shù)據(jù)統(tǒng)計

2015-07-06 13:36:14

Redis微博關(guān)注關(guān)系

2009-03-24 13:04:55

匯總組織結(jié)構(gòu)Oracle

2021-03-17 08:11:21

SQL工作日數(shù)據(jù)

2024-06-11 10:03:56

2019-09-11 10:23:58

Redis性能存儲

2023-03-20 07:27:43

2015-04-22 14:41:04

云遷移Redis緩存數(shù)據(jù)模型調(diào)整

2024-10-06 12:50:25

2021-03-22 11:10:09

Redis架構(gòu)MQ

2025-06-09 08:21:55

2024-10-05 16:00:00

谷歌開源模型

2022-08-11 18:27:50

面試Redis分布式鎖

2021-08-04 17:55:38

keysRedis數(shù)據(jù)庫

2019-11-26 11:19:40

統(tǒng)計數(shù)據(jù)互聯(lián)網(wǎng)

2024-03-27 07:55:58

SpringRedis海量
點贊
收藏

51CTO技術(shù)棧公眾號