日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis站点流量统计HyperLogLog

發布時間:2025/3/17 数据库 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis站点流量统计HyperLogLog 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在我們做站點流量統計的時候一般會統計頁面UV(獨立訪客:unique visitor)和PV(即頁面瀏覽量:page view),那么我們最常見的處理方式就是用戶點擊一次就插入一條數據到數據庫,統計的時候通過查詢表來達到統計流量的效果。

那么我們如果是通過redis來處理,我們可以使用string類型然后自增計數即可達到統計PV,統計UV可以使用set,每個用戶id是唯一的可以放到這個集合里,統計的時候只需要執行scard獲取集合大小即可。

這兩種方式都是可以實現站點的流量統計,但是如果說當站點流量非常大每天幾千萬次的訪問量,那么數據庫可能就要分表分庫了,redis添加足夠多的數據后內存消耗也是非常驚人的,總的來說這樣做是不劃算的,那么我們的redis有一種專門處理這樣數據的算法,HyperLogLog。

HyperLogLog基本使用方式

HyperLogLog提供了兩個指令pfadd和pfcount,根據字面意思很好理解,一個是增加計數,一個是獲取計數。pfadd和set集合的sadd的用法是一樣的,pfcount和scard的用法是一樣的,直接獲取計數值。

HyperLogLog還提供一個合并的指令pfmerge,用于將兩個pf累加形成一個新的pf,如果說我們需要將每個頁面的流量合并,那么我們這個指令大有用處。

> pfadd user mango(integer) 1> pfadd user zhangsan(integer) 1> pfadd user lisi(integer) 1>?pfadd?user?mango?????#重復則不計數(integer) 0> pfcount user(integer) 3?> pfadd paper mango(integer) 1> pfadd paper zhangsan(integer) 1>?pfmerge?pv?user?paper????#合并OK> pfcount pv(integer) 3

注意:

  • HyperLogLog的計數統計是有一定的誤差的,誤差最大在1%以下。

  • HyperLogLog數據結構需要占據12KB的存儲空間,所以我們在使用的時候得注意,如果數據量非常小我們可以選擇其他方式,但是如果是數據量非常大,那么我們這個數據結構就非常有價值了。但是我們也不要太過于擔心它的消耗,一開始初始的時候是沒有這么大的,在計數比較小時他是采用稀疏矩陣來進行存儲,空間占用率還是很小的,只有到達一定閾值后才會轉變成稠密矩陣空間才會到達12KB。

  • 命令pf前綴的由來

    我們使用這個HyperLogLog命令的時候有點奇怪的感覺,因為我們使用hash的時候都是h開頭hadd,set都是sadd,zset都是z開頭,那么我們的HyperLogLog為啥是個pf呢?HyperLogLog這個數據結構的發明人Philippe Flajolet, pf 是他的名字的首字母縮寫。

    HyperLogLog實現原理

    HyperLogLog實際上不會存儲每個元素的值,它使用的是概率算法,通過存儲元素的hash值的第一個1的位置,來計算元素數量。

    我們第一次產生的隨機值獲取到它的二進制,從右往左計數連續0的個數,每次獲取這個數出現1和0的概率都是1/2,k在任意回合出現的概率即為(1/2)^k,因此可以推測n=2^k,但是一般來講n的值會在2^k和2^k之間徘徊,為了要讓這個算法更加準確,于是引入了桶的概念,計算m個桶的加權平均值,這樣就能得到比較準確的答案了(實際上還要進行其他修正)。最終的公式如圖

    其中m是桶的數量,const是修正常數,它的取值會根據m而變化。p=log2m

    switch (p) { case 4: constant = 0.673 * m * m; case 5: constant = 0.697 * m * m; case 6: constant = 0.709 * m * m; default: constant = (0.7213 / (1 + 1.079 / m)) * m * m;}

    有興趣看源碼的同學可以去github上查看redis HyperLogLog的代碼實現,考慮到篇幅太多,讀起來緊張我們這里就不貼源代碼了

    HyperLogLog相關的命令有三個:

    pfadd hll ele:將ele添加進hll的基數計算中。流程:

  • 先對ele求hash(使用的是一種叫做MurMurHash的算法)?

  • 將hash的低14位(因為總共有2的14次方個桶)作為桶的編號,選桶,記桶中當前的值為count

  • 從的hash的第15位開始數0,假設從第15位開始有n個連續的0(即前導0)

  • 如果n大于count,則把選中的桶的值置為n,否則不變

  • pfcount hll:計算hll的基數。就是使用上面給出的DV公式根據桶中的數值,計算基數

    pfmerge hll3 hll1 hll2:將hll1和hll2合并成hll3。合并方法是將所有的HyperLogLog對象合并到一個名為max的對象中,max采用的? 是密集存儲結構,如果被合并的對象也是密集存儲結構,則循環比較每一個計數值,將大的那個存入max。

    Redis的所有HyperLogLog結構都是固定的16384個桶(2的14次方),并且有兩種存儲格式:

    • 稀疏格式:HyperLogLog算法在剛開始的時候,大多數桶其實都是0,稀疏格式通過存儲連續的0的數目,而不是每個0存一遍,大大減小了HyperLogLog剛開始時需要占用的內存

    • 緊湊格式:用6個bit表示一個桶,需要占用12KB內存

    pf 的內存占用為什么是 12k?
    我們在上面的算法中使用了1024個桶進行獨立計數,不過在Redis的HyperLogLog實現中用到的是16384個桶,也就是2^14,每個桶的maxbits需要6個bits來存儲,最大可以表示maxbits=63,于是總共占用內存就是2^14 * 6/8 = 12k 字節。

    ?

    ?

    一名正在搶救的coder

    筆名:mangolove

    CSDN地址:https://blog.csdn.net/mango_love

    GitHub地址:https://github.com/mangoloveYu

    ?

    新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!

    總結

    以上是生活随笔為你收集整理的Redis站点流量统计HyperLogLog的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。