redis學習筆記之-(3)-HyperLogLogs(HLL)的使用

上一篇: redis學習筆記之-(2)-bitmap用法之2-上億用戶1周連續活躍用戶數統計redis


3.1 HLL簡介:Counting unique things

bitmap能夠統計活躍用戶數 , 甚至能夠遍歷出是那些用戶id; 而 HyperLogLogs(簡稱HLL)是一個機率數據結構,用於估計集合的基數(只求unique的總數). 本質上, HLL並不是數據結構而是一種基數算法,經過HLL可用極小內存完成海量元素集合基數總量的統計;算法

基數: 不重複元素, 好比{1, 2, 3, 5, 5, 5, 6}, 基數集爲{1, 2, 3, 5, 6}, 基數爲5;
  • HLL是一種算法; 只計算基數, 不會存儲基數集元素自己; 您並未真正將項目添加到HLL中;
  • HyperLogLogs 提供了3個命令:pfadd pfcount pfmerge
  • 相似於set集合的scard set
  • 最終獲得帶有標準偏差的估計量,在Redis實現的狀況下,該偏差小於1%shell

    近似爲0.81%的標準偏差
  • 該算法的神奇之處在於,不需用與所計數項目數成正比的內存量,而是使用恆定數量的內存!segmentfault

    在最壞的狀況下爲12k字節
  • 該偏差小於1%

3.2 關於pfadd命令的前綴pf的來源

redis之父antirez, 在他的博客中有說起: -->看來是爲了致敬Philippe Flajolet數據結構

Redis new data structure: the HyperLogLogapp

There is a class of algorithms that use randomization in order to provide an approximation of the number of unique elements in a set using just a constant, and small, amount of memory. The best of such algorithms currently known is called HyperLogLog, and is due to Philippe Flajolet.

3.3 命令

  • 加入一個元素: pfadd key element [element...]
  • 計算已加入的元素的unique數: pfcount key [key...]
  • 合併多個統計的hyperloglog爲一個: pfmerge destkey sourcekey [sourcekey...]

3.4 案例使用

  • 每有一個新元素, 使用PFADD加入計數;
  • 想要查看當前加入元素的unique量的近似值, 使用PFCOUNT;
  • 也能夠合併多個HyperLogLog的基數到一箇中, 使用PFMERGE;

(1). 簡單案例: 兩個hyperloglog, 一個hll1, 一個hll2, 最後合併兩個到 hllres中:dom

127.0.0.1:6379> pfadd hll1 a b c d e
(integer) 1
127.0.0.1:6379> pfadd hll1 a b c e f
(integer) 1
127.0.0.1:6379> pfadd hll1 h
(integer) 1
127.0.0.1:6379> pfcount hll1
(integer) 7
127.0.0.1:6379> pfadd hll2 h i j k l m
(integer) 1
127.0.0.1:6379> pfadd hll2 k l m n o o p
(integer) 1
127.0.0.1:6379> pfcount hll2
(integer) 9
127.0.0.1:6379> pfmerge hllres hll1 hll2
OK
127.0.0.1:6379> pfcount hllres
(integer) 15

(2). 實際生產中咱們能夠操做的數據集可能有: 能夠是IP、Email、ID等;ide

IP : 統計網站的日UV;學習

email: 統計全部收到郵件的總數;網站

ID: 統計海量日誌中記錄的訪問ID的不重複值的總數;

(3). 實用: 假若有一個需求是:

經過攝像頭拍攝記錄經海路地鐵站的十字路口的交通情況, 計算一天通過的車輛總集合的基數, 用於估算附近車輛總數. ==> 目標很簡單, 就是記錄通過紅綠燈的車牌號, 一成天的unique總量;

來統計經過路口的汽車的總量: 假設咱們上午統計一次(hll_traff_am), 下午統計一次(hll_traff_pm), 最後彙總(hll_traff_allday)

#1. 上午統計入 hyperloglog hll_traff_am
127.0.0.1:6379> pfadd hll_traff_am 京AF1234 京Q12345 陝A7804s 京AS2235 京P82333 陝A7804s 京AS2235 陝A7804s
(integer) 1
#2. 下午統計入 hyperloglog hll_traff_pm
127.0.0.1:6379> pfadd hll_traff_pm 京A00001 京B00001 陝A00001 京AS2235 京P00001 陝A7804s 陝A7804s
(integer) 1
127.0.0.1:6379> pfcount hll_traff_am
(integer) 5
127.0.0.1:6379> pfcount hll_traff_pm
(integer) 6
#3. 合併到總體的統計: hll_traff_allday
127.0.0.1:6379> pfmerge hll_traff_allday hll_traff_am hll_traff_pm
OK
127.0.0.1:6379> pfcount hll_traff_allday
(integer) 9
127.0.0.1:6379>

當車流量更大, 時間更多, 好比一全年, 這個統計更高效;

注意: 這個得是在能容忍有<1%的偏差率的前提下才可用; 好比, 我算DAU, 網站的日訪問量, 我能容忍實際的101w次, 實際只獲得100w;

相關文章
相關標籤/搜索