1. 程式人生 > >redis的HyperLogLog學習小結

redis的HyperLogLog學習小結

學習掘金小冊所得:
我們先思考一個常見的業務問題:如果你負責開發維護一個大型的網站,有一天老闆找產品經理要網站每個網頁每天的 UV 資料,然後讓你來開發這個統計模組,你會如何實現?
如果統計 PV 那非常好辦,給每個網頁一個獨立的 Redis 計數器就可以了,這個計數器的 key 字尾加上當天的日期。這樣來一個請求,incrby 一次,最終就可以統計出所有的 PV 資料。 但是 UV 不一樣,它要去重,同一個使用者一天之內的多次訪問請求只能計數一次。這就要求每一個網頁請求都需要帶上使用者的 ID,無論是登陸使用者還是未登陸使用者都需要一個唯一 ID 來標識。 你也許已經想到了一個簡單的方案,那就是為每一個頁面一個獨立的 set 集合來儲存所有當天訪問過此頁面的使用者 ID。當一個請求過來時,我們使用 sadd 將使用者 ID 塞進去就可以了。通過 scard 可以取出這個集合的大小,這個數字就是這個頁面的 UV 資料。沒錯,這是一個非常簡單的方案。 但是,如果你的頁面訪問量非常大,比如一個爆款頁面幾千萬的 UV,你需要一個很大的 set 集合來統計,這就非常浪費空間。如果這樣的頁面很多,那所需要的儲存空間是驚人的。為這樣一個去重功能就耗費這樣多的儲存空間,值得麼?其實老闆需要的資料又不需要太精確,105w 和 106w 這兩個數字對於老闆們來說並沒有多大區別,So,有沒有更好的解決方案呢? 這就是本節要引入的一個解決方案,Redis 提供了 HyperLogLog 資料結構就是用來解決這種統計問題的。HyperLogLog 提供不精確的去重計數方案,雖然不精確但是也不是非常不精確,標準誤差是 0.81%,這樣的精確度已經可以滿足上面的 UV 統計需求了。 HyperLogLog 資料結構是 Redis 的高階資料結構,它非常有用,但是令人感到意外的是,使用過它的人非常少。

使用方法

HyperLogLog 提供了兩個指令 pfadd 和 pfcount,根據字面意義很好理解,一個是增加計數,一個是獲取計數。pfadd 用法和 set 集合的 sadd 是一樣的,來一個使用者 ID,就將使用者 ID 塞進去就是。pfcount 和 scard 用法是一樣的,直接獲取計數值。... 

HyperLogLog 這個資料結構不是免費的,不是說使用這個資料結構要花錢,它需要佔據一定 12k 的儲存空間,所以它不適合統計單個使用者相關的資料。如果你的使用者上億,可以算算,這個空間成本是非常驚人的。但是相比 set 儲存方案,HyperLogLog 所使用的空間那真是可以使用千斤對比四兩來形容了。 不過你也不必過於當心,因為 Redis 對 HyperLogLog 的儲存進行了優化,在計數比較小時,它的儲存空間採用稀疏矩陣儲存,空間佔用很小,僅僅在計數慢慢變大,稀疏矩陣佔用空間漸漸超過了閾值時才會一次性轉變成稠密矩陣,才會佔用 12k 的空間。... https://juejin.im 掘金 — 一個幫助開發者成長的社群