【SpringBoot DB 系列】Redis 高級特性之 HyperLoglog

【SpringBoot DB 系列】Redis 高級特性之 HyperLoglog

hyperloglog 算法,利用非常少的空間,實現比較大的數據量級統計;比如我們前面在介紹 bitmap 的過程中,說到了日活的統計,當數據量達到百萬時,最佳的存儲方式是 hyperloglog,本文將介紹一下 hyperloglog 的基本原理,以及 redis 中的使用姿勢

I. 基本使用

1. 配置

我們使用 SpringBoot 2.2.1.RELEASE來搭建項目環境,直接在pom.xml中添加 redis 依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

如果我們的 redis 是默認配置,則可以不額外添加任何配置;也可以直接在application.yml配置中,如下

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password:

2. 使用姿勢

我們下來看使用姿勢,原理放在後面說明

redis 中,hyperlolog使用非常簡單,一般就兩個操作命令,添加pfadd + 計數pfcount;另外還有一個不常用的merge

a. add

添加一條記錄

public boolean add(String key, String obj) {
    // pfadd key obj
    return stringRedisTemplate.opsForHyperLogLog().add(key, obj) > 0;
}

b. pfcount

非精準的計數統計

public long count(String key) {
    // pfcount 非精準統計 key的計數
    return stringRedisTemplate.opsForHyperLogLog().size(key);
}

a. merge

將多個 hyperloglog 合併成一個新的 hyperloglog;感覺用的場景並不會特別多

public boolean merge(String out, String... key) {
    // pfmerge out key1 key2  ---> 將key1 key2 合併成一個新的hyperloglog out
    return stringRedisTemplate.opsForHyperLogLog().union(out, key) > 0;
}

3. 原理說明

關於 HyperLogLog 的原理我這裏也不進行詳細贅述,說實話那一套算法以及調和平均公式我自己也沒太整明白;下面大致說一下我個人的樸素理解

Redis 中的 HyperLogLog 一共分了2^14=16384個桶,每個桶佔 6 個 bit

一個數據,塞入 HyperLogLog 之前,先 hash 一下,得到一個 64 位的二進制數據

  • 取低 14 位,用來定位桶的 index
  • 高 50 位,從低到高數,找到第一個爲 1 出現的位置 n
    • 若桶中值 > n,則丟掉
    • 反之,則設置桶中的值爲 n

那麼怎麼進行計數統計呢?

  • 拿所有桶中的值,代入下面的公式進行計算

上面這個公式怎麼得出的?

之前看到一篇文章,感覺不錯,有興趣瞭解原理的,可以移步: https://www.jianshu.com/p/55defda6dcd2

4. 應用場景

hyperloglog通常是用來非精確的計數統計,前面介紹了日活統計的 case,當時使用的是 bitmap 來作爲數據統計,然而當 userId 分散不均勻,小的特別小,大的特別大的時候,並不適用

在數據量級很大的情況下,hyperloglog的優勢非常大,它所佔用的存儲空間是固定的2^14
下圖引用博文《用戶日活月活怎麼統計》

使用 HyperLogLog 進行日活統計的設計思路比較簡單

  • 每日生成一個 key
  • 某個用戶訪問之後,執行 pfadd key userId
  • 統計總數: pfcount key

II. 其他

0. 項目

系列博文

工程源碼

1. 一灰灰 Blog

盡信書則不如,以上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現 bug 或者有更好的建議,歡迎批評指正,不吝感激

下面一灰灰的個人博客,記錄所有學習和工作中的博文,歡迎大家前去逛逛

一灰灰blog

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章