(1)HyperLogLog簡介
在Redis 在 2.8.9 版本才添加了 HyperLogLog,HyperLogLog算法是用於基數統計的算法,每一個 HyperLogLog 鍵只須要花費 12 KB 內存,就能夠計算接近 2^64 個不一樣元素的基數。HyperLogLog適用於大數據量的統計,由於成本相對來講是更低的,最多也就佔用12kb內存
業務場景,HyperLogLog經常使用於大數據量的統計,好比頁面訪問量統計或者用戶訪問量統計
舉個例子,假如要統計一個頁面的訪問量(PV),這個還比較好辦,能夠直接用redis計數器或者直接存數據庫均可以作,而後若是再加需求,如今要統計一個頁面的用戶訪問量(UV),一個用戶一天內若是訪問屢次的話,也只能算一次,這樣的話,你可能會想到用SET集合來作,由於SET集合是有去重功能的,key存儲頁面對應的關鍵字,value存儲對應userId,這種方法是可行,但是訪問量一多的話,假若有幾千萬訪問量,那就麻煩了,爲了統計一個訪問量,要頻繁建立SET集合對象
那有其它方法嗎?針對上面大訪問量的狀況,redis是有實現了HyperLogLog算法,HyperLogLog 這個數據結構的發明人 是Philippe Flajolet 教授
Redis集成的HyperLogLog使用語法主要有pfadd和pfcount,顧名思義,一個是來添加數據,一個是來統計的,使用比較容易掌握,不過算法是比較複雜的,而後爲何用pf?是由於HyperLogLog 這個數據結構的發明人 是Philippe Flajolet教授 ,因此用發明人的英文縮寫,這樣咱們也容易記住這個語法了
下面給出一些簡單例子,啓動redis客戶端
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> pfadd uv user1
(integer) 1
127.0.0.1:6379> pfcount uv
(integer) 1
127.0.0.1:6379> pfadd uv user2
(integer) 1
127.0.0.1:6379> pfcount uv
(integer) 2
127.0.0.1:6379> pfadd uv user3
(integer) 1
127.0.0.1:6379> pfcount uv
(integer) 3
127.0.0.1:6379> pfadd uv user4
(integer) 1
127.0.0.1:6379> pfcount uv
(integer) 4
127.0.0.1:6379> pfadd uv user5 user6 user 7 user8 user9 user10
(integer) 1
127.0.0.1:6379> pfcount uv
(integer) 10
127.0.0.1:6379>
而後用java的Jedis庫來實現
加上Maven:
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
</dependencies>
寫個測試類,要先啓動redis服務端
package com.test.redis;
import redis.clients.jedis.Jedis;
public class RedisPFCountTest {
public static void main(www.jmaguojiyL.com String[] args) {
Jedis jedis = new Jedis(www.feishenbo.cn"127.0.0.1",6379);
for (int i = 0; i <www.zzxcscl.com 1000; i++) {
jedis.pfadd("pv"www.zheshengjpt.com, String.valueOf(i));
}
long total = jedis.pfcount("pv");
System.out.printf("%d\n", total);
jedis.close();
}
}
在這裏插入圖片描述
再加大數據量,這裏寫了10萬次的統計,能夠看出是有一點偏差的
在這裏插入圖片描述
固然HyperLogLog算法一開始就是爲了大數據量的統計而發明的,因此很適合那種數據量很大,而後又沒要求不能有一點偏差的計算,HyperLogLog 提供不精確的去重計數方案,雖然不精確可是也不是很是不精確,標準偏差是 0.81%,不過這對於頁面用戶訪問量是沒影響的,由於這種統計多是訪問量很是巨大,可是又不必作到絕對準確,訪問量對準確率要求沒那麼高,可是性能存儲方面要求就比較高了,而HyperLogLog正好符合這種要求,不會佔用太多存儲空間,同時性能不錯
(2) PFMERGE 用法
pfadd和pfcount經常使用於統計,而後來個需求,假如兩個頁面很相近,如今想統計這兩個頁面的用戶訪問量呢?這裏就能夠用pfmerge合併統計了,語法如例子:
127.0.0.1:6379> PFADD test1 "apple" "banana" "cherry"
(integer) 1
127.0.0.1:6379> PFCOUNT test1
(integer) 3
127.0.0.1:6379> PFADD test2 "apple" "cherry" "durian" "mongo"
(integer) 1
127.0.0.1:6379> PFCOUNT test2
(integer) 4
127.0.0.1:6379> PFMERGE test1&test2 test1 test2
OK
127.0.0.1:6379> PFCOUNT test1&test2
(integer) 5java