Redis HyperLogLog介紹及應用

_天道酬勤_發表於2020-04-04

簡介

Redis 在 2.8.9 版本新增了 HyperLogLog 結構

HyperLogLog 是用來做基數統計的演算法,即對集合去重元素的計數

在輸入元素的數量不超過2^64個,計算基數所需的記憶體最多12KB,該結構使用一種近似值演算法,標準誤差0.81%。

計算基數的方法分析

使用一般集合計算

隨著統計元素的增加,記憶體消耗也劇增,資源消耗嚴重,不適合大資料量統計

bitmap

用位陣列來表示各元素是否出現,每個元素對應一位,所需的總記憶體為n bit。能大大減少記憶體佔用且位操作迅速。

如果要統計1億個資料的基數值,大約需要記憶體100000000/8/1024/1024 ≈ 12M,記憶體減少佔用的效果顯著。然而統計一個物件的基數值需要12M,如果統計10000個物件,就需要將近120G,同樣不能廣泛用於大資料場景

但是這個方法是精確計算

概率演算法

目前用於基數計數的概率演算法包括:

  • Linear Counting(LC):早期的基數估計演算法,LC在空間複雜度方面並不算優秀,實際上LC的空間複雜度與上文中簡單bitmap方法是一樣的(但是有個常數項級別的降低),都是O(Nmax)
  • LogLog Counting(LLC):LogLog Counting相比於LC更加節省記憶體,空間複雜度只有O(log2(log2(N​max)))
  • HyperLogLog Counting(HLL):HyperLogLog Counting是基於LLC的優化和改進,在同樣空間複雜度情況下,能夠比LLC的基數估計誤差更小

演算法白話說明

通俗點說明: 假設我們為一個資料集合生成一個8位的雜湊串,那麼我們得到00000111的概率是很低的,也就是說,我們生成大量連續的0的概率是很低的。生成連續5個0的概率是1/32,那麼我們得到這個串時,可以估算,這個資料集的基數是32

應用場景

適用場景特點

  • 非精確統計,HyperLogLog是近似值演算法,有0.81%標準誤差
  • 資料量巨大,不大就用不上,大材小用,浪費空間
  • 只能統計集合基數(去重)數量,而沒辦法去知道具體的內容,自然也沒辦法返回集合元素

應用場景舉例

  • 統計 IP 數
  • 統計 UV 數
  • 統計使用者每天搜尋不同詞條個數

命令說明

pfadd

PFADD key element [element ...]

時間複雜度: O(1) to add every element

功能說明: 新增元素到計算空間

返回值

  • 如果同時指定了key和element,那麼如果執行命令後HyperLogLog的近視基數發生了變化,則返回1,否則返回0
  • 如果只指定了key,那麼如果Key存在,返回0,否則建立key,返回1

示例: PFADD hll a b c d e f g

PFCOUNT

PFCOUNT key [key ...]

時間複雜度

  • 使用單個鍵呼叫時,O(1)的平均恆定時間非常短。
  • 使用多個鍵時,O(N)N是鍵的數目,並且在使用多個鍵呼叫時,常數時間要大得多

功能說明: 計算傳入的所有key對應的元素集合去重基數

返回值: 基數計數近似值(標準誤差約0.81%)

示例: pfcount hll hll2

特別說明

作為呼叫此函式的副作用,HyperLogLog可能會被修改,因為後8個位元組編碼用於快取目的的最新計算基數。因此從技術上講PFCOUNT是寫命令

當用單個鍵呼叫PFCOUNT時,效能也很出色,PFCOUNT使用快取來記住先前計算的基數,這種變化很少改變,因為大多數PFADD操作不會更新任何暫存器

當PFCOUNT呼叫多個key時,HyperLogLogs需要合併計算,這是緩慢的,而且合併的基數不能被快取,所以有多個key使用時PFCOUNT可能需要的時間在一個毫秒級的數量級,不應濫用

PFMERGE

PFMERGE destkey sourcekey [sourcekey ...]

時間複雜度: O(N)合併N個HyperLogLogs,但是具有恆定的時間

功能說明: 將sourcekey 合併到 destkey, 如果destkey不存在,則新建立一個空的HyperLogLog,如果destkey存在,則將其視為sourcekey之一

返回值: 只返回ok

示例: PFMERGE hll3 hll1 hll2

參考文章

Redis命令說明

Redis new data structure: the HyperLogLog

Redis:HyperLogLog使用與應用場景

神奇的HyperLogLog演算法

相關文章