HyperLogLog簡介
HyperLogLog 並不是一種新的資料結構(實際型別為字串型別),而是一種基數演算法,通過 HyperLogLog 可以利用極小的記憶體空間完成獨立總數的統計,資料集可以是 IP、Email、ID 等。
命令
新增
PFADD
自2.8.9可用。
時間複雜度:每新增一個元素的複雜度為 O(1) 。
語法:PFADD key element [element …]
說明:
將任意數量的元素新增到指定的 HyperLogLog 裡面。
作為這個命令的副作用, HyperLogLog 內部可能會被更新, 以便反映一個不同的唯一元素估計數量(也即是集合的基數)。
如果 HyperLogLog 估計的近似基數(approximated cardinality)在命令執行之後出現了變化, 那麼命令返回 1
, 否則返回 0
。 如果命令執行時給定的鍵不存在, 那麼程式將先建立一個空的 HyperLogLog 結構, 然後再執行命令。
呼叫 PFADD
命令時可以只給定鍵名而不給定元素:
- 如果給定鍵已經是一個 HyperLogLog , 那麼這種呼叫不會產生任何效果;
-
但如果給定的鍵不存在, 那麼命令會建立一個空的 HyperLogLog , 並向客戶端返回
1
。
返回值:
整數回覆: 如果 HyperLogLog 的內部儲存被修改了, 那麼返回 1 , 否則返回 0 。
示例:
coderknock> PFADD databases "Redis" "MongoDB" "MySQL"
(integer) 1
coderknock> PFCOUNT databases
(integer) 3
coderknock> PFADD databases "Redis" # Redis 已經存在,不必對估計數量進行更新
(integer) 0
coderknock> PFCOUNT databases # 元素估計數量沒有變化
(integer) 3
coderknock> PFADD databases "PostgreSQL" # 新增一個不存在的元素
(integer) 1
coderknock> PFCOUNT databases # 估計數量增一
4
計算總數
PFCOUNT
自2.8.9可用。
時間複雜度:當命令作用於單個 HyperLogLog 時, 複雜度為 O(1) , 並且具有非常低的平均常數時間。 當命令作用於 N 個 HyperLogLog 時, 複雜度為 O(N) , 常數時間也比處理單個 HyperLogLog 時要大得多。
語法:PFCOUNT key [key …]
說明:
當 PFCOUNT
命令作用於單個鍵時, 返回儲存在給定鍵的 HyperLogLog 的近似基數, 如果鍵不存在, 那麼返回 0
。
當 PFCOUNT
命令作用於多個鍵時, 返回所有給定 HyperLogLog 的並集的近似基數, 這個近似基數是通過將所有給定 HyperLogLog 合併至一個臨時 HyperLogLog 來計算得出的。
通過 HyperLogLog 資料結構, 使用者可以使用少量固定大小的記憶體, 來儲存集合中的唯一元素 (每個 HyperLogLog 只需使用 12k 位元組記憶體,以及幾個位元組的記憶體來儲存鍵本身)。
命令返回的可見集合(observed set)基數並不是精確值, 而是一個帶有 0.81% 標準錯誤(standard error)的近似值。
舉個例子, 為了記錄一天會執行多少次各不相同的搜尋查詢, 一個程式可以在每次執行搜尋查詢時呼叫一次 PFADD
, 並通過呼叫 PFCOUNT
命令來獲取這個記錄的近似結果。
返回值:
整數回覆: 給定 HyperLogLog 包含的唯一元素的近似數量。
示例:
coderknock> PFADD databases "Redis" "MongoDB" "MySQL"
(integer) 1
coderknock> PFCOUNT databases
(integer) 3
coderknock> PFADD databases "Redis" # Redis 已經存在,不必對估計數量進行更新
(integer) 0
coderknock> PFCOUNT databases # 元素估計數量沒有變化
(integer) 3
coderknock> PFADD databases "PostgreSQL" # 新增一個不存在的元素
(integer) 1
coderknock> PFCOUNT databases # 估計數量增一
4
整合
PFMERGE
自2.8.9可用。
時間複雜度:O(N) , 其中 N 為被合併的 HyperLogLog 數量, 不過這個命令的常數複雜度比較高。
語法:PFMERGE destkey sourcekey [sourcekey …]
說明:
將多個 HyperLogLog 合併(merge)為一個 HyperLogLog , 合併後的 HyperLogLog 的基數接近於所有輸入 HyperLogLog 的可見集合(observed set)的並集。
合併得出的 HyperLogLog 會被儲存在 destkey
鍵裡面, 如果該鍵並不存在, 那麼命令在執行之前, 會先為該鍵建立一個空的 HyperLogLog 。
返回值:
字串回覆:返回 OK
。
示例:
coderknock> PFADD nosql "Redis" "MongoDB" "Memcached"
(integer) 1
coderknock> PFADD RDBMS "MySQL" "MSSQL" "PostgreSQL" "MySQL"
(integer) 1
coderknock> PFMERGE databases nosql RDBMS
OK
# "MySQL" 重複只記一次
coderknock> PFCOUNT databases
(integer) 6
HyperLogLog 記憶體佔用量非常小,但是存在錯誤率,開發者在進行資料結構選型時只需要確認如下兩條即可:
-
只為了計算獨立總數,不需要獲取單條資料。
-
可以容忍一定誤差率,畢竟HyperLogLog在記憶體的佔用量上有很大的優勢。