Redis中 HyperLogLog資料型別使用總結

2023-03-11 18:01:44

轉載請註明出處:

目錄

  1. HyperLogLog 的原理

  2.使用步驟

  3.實現請求ip去重的瀏覽量使用範例

  4.Jedis使用者端使用

  5.Redission使用依賴

  6.HyperLogLog 提供了哪些特性和方法

  7.使用場景總結

1. HyperLogLog 的原理

  Redis HyperLogLog基於一種稱為HyperLogLog演演算法的概率性演演算法來估計基數。 HyperLogLog使用一個長度為m的位陣列和一些hash函數來估計集合中的唯一元素數。

在 HyperLogLog 演演算法中,對每個元素進行雜湊處理,把雜湊值轉換為二進位制後,根據二進位制串字首中 1 的個數來給每個元素打分。例如,一個元素的雜湊值為01110100011,那麼字首中1的個數是3,因此在 HyperLogLog 演演算法中,這個元素的分數為3。

  當所有元素的分數統計完之後,取每一個分數的倒數(1 / 2^n),然後將這些倒數相加後取倒數,就得到一個基數估計值,這個值就是HyperLogLog演演算法的估計結果。

  HyperLogLog演演算法通過對位陣列的長度m的大小進行取捨,折衷資料結構佔用的記憶體與估計值的精準度(即估計誤差),得到了在資料佔用空間與錯誤較小程度之間完美的平衡。

  簡而言之,HyperLogLog演演算法的核心思想是基於雜湊函數和位運算,通過將雜湊值轉換成位元流並統計前導0的個數,從而快速估算大型資料集中唯一值的數量。通過 hyperloglog 演演算法我們可以在非常大的資料集中進行極速的網頁瀏覽器去重。

2.使用步驟:

  Redis HyperLogLog是一種可用於估算集合中元素數量的資料結構,它能夠通過使用非常少的記憶體來維護海量的資料。它的精確度要比使用一般的估計演演算法高,並且在處理大量資料時的速度也非常快。

  一個簡單的例子,我們可以用HyperLogLog來計算存取網站的獨立IP數,具體可以按以下步驟操作:

    1. 首先建立一個HyperLogLog資料結構:  PFADD hll:unique_ips 127.0.0.1

    2. 為每次存取ip新增到unique_ips資料結構中:         PFADD hll:unique_ips 192.168.1.1

    3. 獲取計算集合中元素數量的近似值:           PFCOUNT hll:unique_ips

    4. 可以通過對多個HyperLogLog結構(例如按天或按小時)的合併,來獲得更精確的計數。

  需要注意的是,HyperLogLog雖然可以節省大量的記憶體,但它是一種估計演演算法,誤差範圍並不是完全精確的,實際使用時應注意其適用範圍。

3.實現請求ip去重的瀏覽量使用範例

4.Jedis使用者端使用

  1. 新增依賴,引入jedis依賴:

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.6.0</version>
</dependency>

  2.建立一個Jedis物件:

Jedis jedis = new Jedis("localhost");

  3.向HyperLogLog資料結構新增元素:

jedis.pfadd("hll:unique_ips", "127.0.0.1");

  4. 獲取計算集合中元素數量的近似值:

Long count = jedis.pfcount("hll:unique_ips");
System.out.println(count);

  5.可以通過對多個HyperLogLog結構的合併來獲得更精確的計數。在Jedis中可以使用PFMERGE命令來合併HyperLogLog資料結構:

jedis.pfmerge("hll:unique_ips", "hll:unique_ips1", "hll:unique_ips2", "hll:unique_ips3");

5.Redission使用依賴

  1.建立RedissonClient物件

Config config = new Config();
config.useSingleServer().setAddress("redis://localhost:6379");
RedissonClient redisson = Redisson.create(config);

  2.建立RHyperLogLog物件

RHyperLogLog<String> uniqueIps = redisson.getHyperLogLog("hll:unique_ips");

  3.新增元素

uniqueIps.add("127.0.0.1");

  4..獲取近似數量

long approximateCount = uniqueIps.count();
System.out.println(approximateCount);

  5.合併多個HyperLogLog物件

RHyperLogLog<String> uniqueIps1 = redisson.getHyperLogLog("hll:unique_ips1");
RHyperLogLog<String> uniqueIps2 = redisson.getHyperLogLog("hll:unique_ips2");
uniqueIps.mergeWith(uniqueIps1, uniqueIps2);

6.HyperLogLog 提供了哪些特性和方法

  特性:

    1. 精確度低,但佔用記憶體極少。

    2. 支援插入新元素,同時不會重複計數。

    3. 提供指令來優化記憶體使用和計數準確性。例如PFADD、PFCOUNT、PFMERGE等指令。

    4. 能夠估計一個資料集中的不同元素數量,即集合的基數(cardinality)。

    5. 支援對多個HyperLogLog物件進行合併操作,以獲得這些集合的總基數的近似值。

  HyperLogLog常用的方法:

    1. PFADD key element [element ...]:新增一個或多個元素到HyperLogLog結構中。

    2. PFCOUNT key [key ...]:獲取一個或多個HyperLogLog結構的基數估計值。

    3. PFMERGE destkey sourcekey [sourcekey ...]:合併一個或多個HyperLogLog結構到一個目標結構中。

    4. PFSELFTEST [numtests]: 測試HyperLogLog估值效能和準確性(僅限Redis4.0+版本)

  需要注意的是,HyperLogLog雖然可以節省大量記憶體,但仍然是一種估計演演算法,誤差範圍並不是完全精確的,並且具有一定的計算成本。在使用時需要根據實際應用情況選擇是否使用HyperLogLog或其他資料結構來估計元素數量。

7.使用場景總結:

  Redis使用HyperLogLog的主要作用是在巨量資料流(view,IP,城市)的情況下進行去重計數。

  具體來說,以下是Redis HyperLogLog用於去重計數的一些場景:

    1. 統計頁面存取量 - 在Web應用程式中, HyperLogLog可以使用為每個頁面計算多少次獨特的存取者。通過跨越多個不同的時間段使用HyperLogLog,可以計算出這個頁面的所有時間的平均存取數。

    2. 統計使用者數 - 在分析巨量資料集合的使用者數量方面,HyperLogLog也非常有用。作為一種基於概率的資料結構,尤其是在處理獨特的使用者ID這樣的資料集合時。在此情況下,HyperLogLog首先執行雜湊,此後僅在內部儲存有限的雜湊值,同時還能夠推斷大小。

    3. 統計廣告點選量 - 對於網站或應用程式的廣告分析,HyperLogLog可以用於捕獲有效點選數量,即非重複或唯一點選數量。

  總之,對於需要進行去重計數的巨量資料流的情況下,Redis的HyperLogLog是一種簡單而強大的工具。