企業(yè)網(wǎng)站建設的困難和問題長春seo技術
目錄
前言
HyperLogLog
前言
在學習HyperLogLog之前,我們需要先學習兩個概念
- UV:全稱Unique Visitor,也叫獨立訪客量,是指通過互聯(lián)網(wǎng)訪問、瀏覽這個網(wǎng)頁的自然人。1天內同一個用戶多次訪問該網(wǎng)站,只記錄1次。
- PV:全稱Page View,也叫頁面訪問量或點擊量,用戶每訪問網(wǎng)站的一個頁面,記錄1次PV,用戶多次打開頁面,則記錄多次PV。往往用來衡量網(wǎng)站的流量。
如果UV在服務端做會很麻煩,因為每次都需要判斷該用戶是否已經(jīng)統(tǒng)計過了,因此需要保存統(tǒng)計過的用戶信息,如果都保存在Redis中,大型網(wǎng)站的數(shù)據(jù)量會非常大這種實現(xiàn)方案并不現(xiàn)實。因此,我們需要使用HyperLogLog算法。
HyperLogLog
該算法又可以叫做HLL算法,是從LogLog算法派生的概率算法,用于確定非常大的集合的基數(shù),而不需要存儲其所有值,Redis中的HLL是基于String結構實現(xiàn)的,單個HLL的內存占用永遠不會超過16k,相應的代價是測量結果是概率性的,存在一定誤差,但是可以忽略不計。
對應的命令如下
# 添加用戶ip
PFADD key element [element ...]
# 統(tǒng)計訪問量,在存在多個key的情況下,會對多個key的訪問用戶進行去重后再統(tǒng)計
PFCOUNT key [key ...]
# 合并統(tǒng)計量
PFMERGE destkey sourcekey [sourcekey ...]
接下來我們對該方法進行測試,首先我們對 hll1 這個key進行插入,插入結果如下
那么接下來插入key為 hll2 的數(shù)據(jù),執(zhí)行結果結果如下
在 key 為 hll2 的數(shù)據(jù)完全包含了key為 hll1 的值時,我們對兩個 key 進行聯(lián)合統(tǒng)計,觀察輸出結果
可以看到,我們的統(tǒng)計結果是進行了去重后再進行統(tǒng)計的。那么接下來測試合并方法
hll2 的數(shù)據(jù)會合并到 hll1 中,該方法的存在,我們可以設置ip訪問時設置 key 為年月日,這樣我們可以通過合并每天的key來統(tǒng)計每月的活躍人數(shù)。接下來我們測試HLL的內存占用情況
首先是我們先獲取沒有存儲100w數(shù)據(jù)情況時的內存使用情況,需要注意的時,該值為字節(jié)值,需要我們自己轉化為kb
測試代碼如下,我們需要創(chuàng)建100w的對象來模擬訪問量通過HLL存儲,我們測試Redis的占用情況
@Test
public void test01() throws Exception {String[] str = new String[1000];int j =0;for (int i = 0; i < 1000000; i++) {j = i%1000;str[j] = "user"+i;if (j == 999){stringRedisTemplate.opsForHyperLogLog().add("hll1",str);}}Long count = stringRedisTemplate.opsForHyperLogLog().size("hll1");System.out.println(count);
}
執(zhí)行完測試代碼后的內存占用情況以及統(tǒng)計結果如下,內存占用變?yōu)?900992,統(tǒng)計次數(shù)為 1001788,可以看到存在一定誤差,但是對于100w數(shù)據(jù)來說基本可以忽略不計。
計算添加完數(shù)據(jù)后的內存占用(900992-886608)/1024 ≈ 14k。并且無論執(zhí)行多少次添加數(shù)據(jù)操作,只要對象不發(fā)生改變,永遠統(tǒng)計到的數(shù)量為1001788。