您好,登錄后才能下訂單哦!
這篇文章將為大家詳細(xì)講解有關(guān)Redis站點(diǎn)流量統(tǒng)計(jì)HyperLogLog怎么用,小編覺得挺實(shí)用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
在我們做站點(diǎn)流量統(tǒng)計(jì)的時候一般會統(tǒng)計(jì)頁面UV(獨(dú)立訪客:unique visitor)和PV(即頁面瀏覽量:page view),那么我們最常見的處理方式就是用戶點(diǎn)擊一次就插入一條數(shù)據(jù)到數(shù)據(jù)庫,統(tǒng)計(jì)的時候通過查詢表來達(dá)到統(tǒng)計(jì)流量的效果。
那么我們?nèi)绻峭ㄟ^redis來處理,我們可以使用string類型然后自增計(jì)數(shù)即可達(dá)到統(tǒng)計(jì)PV,統(tǒng)計(jì)UV可以使用set,每個用戶id是唯一的可以放到這個集合里,統(tǒng)計(jì)的時候只需要執(zhí)行scard獲取集合大小即可。
這兩種方式都是可以實(shí)現(xiàn)站點(diǎn)的流量統(tǒng)計(jì),但是如果說當(dāng)站點(diǎn)流量非常大每天幾千萬次的訪問量,那么數(shù)據(jù)庫可能就要分表分庫了,redis添加足夠多的數(shù)據(jù)后內(nèi)存消耗也是非常驚人的,總的來說這樣做是不劃算的,那么我們的redis有一種專門處理這樣數(shù)據(jù)的算法,HyperLogLog。
HyperLogLog提供了兩個指令pfadd和pfcount,根據(jù)字面意思很好理解,一個是增加計(jì)數(shù),一個是獲取計(jì)數(shù)。pfadd和set集合的sadd的用法是一樣的,pfcount和scard的用法是一樣的,直接獲取計(jì)數(shù)值。
HyperLogLog還提供一個合并的指令pfmerge,用于將兩個pf累加形成一個新的pf,如果說我們需要將每個頁面的流量合并,那么我們這個指令大有用處。
> pfadd user mango
(integer) 1
> pfadd user zhangsan
(integer) 1
> pfadd user lisi
(integer) 1
> pfadd user mango #重復(fù)則不計(jì)數(shù)
(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的計(jì)數(shù)統(tǒng)計(jì)是有一定的誤差的,誤差最大在1%以下。
HyperLogLog數(shù)據(jù)結(jié)構(gòu)需要占據(jù)12KB的存儲空間,所以我們在使用的時候得注意,如果數(shù)據(jù)量非常小我們可以選擇其他方式,但是如果是數(shù)據(jù)量非常大,那么我們這個數(shù)據(jù)結(jié)構(gòu)就非常有價(jià)值了。但是我們也不要太過于擔(dān)心它的消耗,一開始初始的時候是沒有這么大的,在計(jì)數(shù)比較小時他是采用稀疏矩陣來進(jìn)行存儲,空間占用率還是很小的,只有到達(dá)一定閾值后才會轉(zhuǎn)變成稠密矩陣空間才會到達(dá)12KB。
HyperLogLog實(shí)際上不會存儲每個元素的值,它使用的是概率算法,通過存儲元素的hash值的第一個1的位置,來計(jì)算元素?cái)?shù)量。
我們第一次產(chǎn)生的隨機(jī)值獲取到它的二進(jìn)制,從右往左計(jì)數(shù)連續(xù)0的個數(shù),每次獲取這個數(shù)出現(xiàn)1和0的概率都是1/2,k在任意回合出現(xiàn)的概率即為(1/2)^k,因此可以推測n=2^k,但是一般來講n的值會在2^k和2^k之間徘徊,為了要讓這個算法更加準(zhǔn)確,于是引入了桶的概念,計(jì)算m個桶的加權(quán)平均值,這樣就能得到比較準(zhǔn)確的答案了(實(shí)際上還要進(jìn)行其他修正)。最終的公式如圖
其中m是桶的數(shù)量,const是修正常數(shù),它的取值會根據(jù)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;}
HyperLogLog相關(guān)的命令有三個:
pfadd hll ele:將ele添加進(jìn)hll的基數(shù)計(jì)算中。流程:
先對ele求hash(使用的是一種叫做MurMurHash的算法)
將hash的低14位(因?yàn)榭偣灿?的14次方個桶)作為桶的編號,選桶,記桶中當(dāng)前的值為count
從的hash的第15位開始數(shù)0,假設(shè)從第15位開始有n個連續(xù)的0(即前導(dǎo)0)
如果n大于count,則把選中的桶的值置為n,否則不變
pfcount hll:計(jì)算hll的基數(shù)。就是使用上面給出的DV公式根據(jù)桶中的數(shù)值,計(jì)算基數(shù)
pfmerge hll3 hll1 hll2:將hll1和hll2合并成hll3。合并方法是將所有的HyperLogLog對象合并到一個名為max的對象中,max采用的是密集存儲結(jié)構(gòu),如果被合并的對象也是密集存儲結(jié)構(gòu),則循環(huán)比較每一個計(jì)數(shù)值,將大的那個存入max。
Redis的所有HyperLogLog結(jié)構(gòu)都是固定的16384個桶(2的14次方),并且有兩種存儲格式:
稀疏格式:HyperLogLog算法在剛開始的時候,大多數(shù)桶其實(shí)都是0,稀疏格式通過存儲連續(xù)的0的數(shù)目,而不是每個0存一遍,大大減小了HyperLogLog剛開始時需要占用的內(nèi)存
緊湊格式:用6個bit表示一個桶,需要占用12KB內(nèi)存
關(guān)于“Redis站點(diǎn)流量統(tǒng)計(jì)HyperLogLog怎么用”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。