Redis實現(xiàn)UV統(tǒng)計的示例代碼
一、HyperLogLog
1、為什么用HyperLogLog
先介紹兩個概念:
UV:全稱 Unique Visitor,也叫獨立訪客量,是指通過互聯(lián)網(wǎng)訪問、瀏覽這個網(wǎng)頁的自然人、1 天內(nèi)同一個用戶多次訪問該網(wǎng)站,只記錄 1 次。
PV:全稱 Page View,也叫頁面訪問量或點擊量,用戶每訪問網(wǎng)站的一個頁面,記錄一次 PV,用戶多次打開頁面,則記錄多次 PV。往往用來衡量網(wǎng)站的流量。
UV 統(tǒng)計在服務端做會比較麻煩,因為要判斷該用戶是否已經(jīng)統(tǒng)計過了,需要將統(tǒng)計過的用戶信息保存。但是如果每個訪問的用戶都保存到Redis 中,數(shù)據(jù)量會非??植?。
那么我們要怎么更好的記錄呢?就用到 HyperLogLog
2、HyperLogLog是什么
HyperLogLog(HLL)是從 Loglog 算法派生的概率算法,用于確定非常大的集合的基數(shù),而不需要存儲其所有值。
Redis 中的 HLL 是基于 String 結(jié)構(gòu)實現(xiàn)的,單個 HLL 的內(nèi)存永遠小于 16kb,內(nèi)存占用低的令人發(fā)指!作為代價,其測量結(jié)果是概率性的,有小于 0.81% 的誤差。不過對于 UV 統(tǒng)計來說,這完全可以忽略。
不管加入多少重復元素,HyperLogLog都只記錄一次,天生適合做uv的統(tǒng)計

二、實現(xiàn)UV統(tǒng)計
我們直接用單元測試,向 HyperLogLog 中添加 100 萬條數(shù)據(jù),看看內(nèi)存占用和統(tǒng)計效果如何:
@Test
void testHyperLogLog() {
String[] values = new String[1000];
int j = 0;
for (int i = 0; i < 1000000; i++) {
j = i % 1000;
values[j] = "user_" + i;
if(j == 999){
// 發(fā)送到 Redis
stringRedisTemplate.opsForHyperLogLog().add("hl2", values);
}
}
// 統(tǒng)計數(shù)量
Long count = stringRedisTemplate.opsForHyperLogLog().size("hl2");
System.out.println("count = " + count);
}測試結(jié)果:
我們統(tǒng)計出來的數(shù)據(jù)跟100萬非常接近,誤差在0.02。而且發(fā)現(xiàn)內(nèi)存只消耗了14kb非常非常低
到此這篇關(guān)于Redis實現(xiàn)UV統(tǒng)計的示例代碼的文章就介紹到這了,更多相關(guān)Redis UV統(tǒng)計內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
基于?Spring?Aop?環(huán)繞通知實現(xiàn)?Redis?緩存雙刪功能(示例代碼)
基于 spring aop 常規(guī)應用場景多是用于日志記錄以及實現(xiàn) redis 分布式鎖,在 github 中也有項目是把它拿來當作緩存的異常捕捉,這篇文章主要介紹了基于?Spring?Aop?環(huán)繞通知實現(xiàn)?Redis?緩存雙刪,需要的朋友可以參考下2022-08-08
Redis緩沖區(qū)溢出是指Redis緩沖區(qū)被寫入的數(shù)據(jù)超過了它的容量,導致數(shù)據(jù)無法存儲或被覆蓋。造成緩沖區(qū)溢出的原因可能是快速寫入大量數(shù)據(jù)、緩沖區(qū)未及時刷新或Redis服務器配置不當?shù)取?/div> 2023-04-04最新評論

