Redis HyperLogLog

拿客_三產發表於2017-06-19

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在記憶體的佔用量上有很大的優勢。

相關文章