【SpringBoot DB 系列】Redis 高級特性之 HyperLoglog
hyperloglog 算法节预,利用非常少的空間格了,實現(xiàn)比較大的數(shù)據(jù)量級統(tǒng)計;比如我們前面在介紹 bitmap 的過程中系瓢,說到了日活的統(tǒng)計慷垮,當數(shù)據(jù)量達到百萬時揖闸,最佳的存儲方式是 hyperloglog,本文將介紹一下 hyperloglog 的基本原理料身,以及 redis 中的使用姿勢
I. 基本使用
1. 配置
我們使用 SpringBoot 2.2.1.RELEASE
來搭建項目環(huán)境汤纸,直接在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
+ 計數(shù)pfcount
饿悬;另外還有一個不常用的merge
a. add
添加一條記錄
public boolean add(String key, String obj) {
// pfadd key obj
return stringRedisTemplate.opsForHyperLogLog().add(key, obj) > 0;
}
b. pfcount
非精準的計數(shù)統(tǒng)計
public long count(String key) {
// pfcount 非精準統(tǒng)計 key的計數(shù)
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. 原理說明
關(guān)于 HyperLogLog 的原理我這里也不進行詳細贅述,說實話那一套算法以及調(diào)和平均公式我自己也沒太整明白乡恕;下面大致說一下我個人的樸素理解
Redis 中的 HyperLogLog 一共分了2^14=16384
個桶言询,每個桶占 6 個 bit
一個數(shù)據(jù)俯萎,塞入 HyperLogLog 之前,先 hash 一下运杭,得到一個 64 位的二進制數(shù)據(jù)
- 取低 14 位夫啊,用來定位桶的 index
- 高 50 位,從低到高數(shù)辆憔,找到第一個為 1 出現(xiàn)的位置 n
- 若桶中值 > n撇眯,則丟掉
- 反之,則設(shè)置桶中的值為 n
那么怎么進行計數(shù)統(tǒng)計呢虱咧?
- 拿所有桶中的值熊榛,代入下面的公式進行計算
上面這個公式怎么得出的?
之前看到一篇文章,感覺不錯腕巡,有興趣了解原理的玄坦,可以移步: http://www.reibang.com/p/55defda6dcd2
4. 應(yīng)用場景
hyperloglog
通常是用來非精確的計數(shù)統(tǒng)計,前面介紹了日活統(tǒng)計的 case绘沉,當時使用的是 bitmap 來作為數(shù)據(jù)統(tǒng)計煎楣,然而當 userId 分散不均勻,小的特別小车伞,大的特別大的時候择懂,并不適用
在數(shù)據(jù)量級很大的情況下,hyperloglog
的優(yōu)勢非常大另玖,它所占用的存儲空間是固定的2^14
下圖引用博文《用戶日活月活怎么統(tǒng)計》
使用 HyperLogLog 進行日活統(tǒng)計的設(shè)計思路比較簡單
- 每日生成一個 key
- 某個用戶訪問之后困曙,執(zhí)行
pfadd key userId
- 統(tǒng)計總數(shù):
pfcount key
II. 其他
0. 項目
系列博文
- 【DB 系列】Redis 高級特性之發(fā)布訂閱
- 【DB 系列】Redis 高級特性之 Bitmap 使用姿勢及應(yīng)用場景介紹
- 【DB 系列】Redis 之管道 Pipelined 使用姿勢
- 【DB 系列】Redis 集群環(huán)境配置
- 【DB 系列】借助 Redis 搭建一個簡單站點統(tǒng)計服務(wù)(應(yīng)用篇)
- 【DB 系列】借助 Redis 實現(xiàn)排行榜功能(應(yīng)用篇)
- 【DB 系列】Redis 之 ZSet 數(shù)據(jù)結(jié)構(gòu)使用姿勢
- 【DB 系列】Redis 之 Set 數(shù)據(jù)結(jié)構(gòu)使用姿勢
- 【DB 系列】Redis 之 Hash 數(shù)據(jù)結(jié)構(gòu)使用姿勢
- 【DB 系列】Redis 之 List 數(shù)據(jù)結(jié)構(gòu)使用姿勢
- 【DB 系列】Redis 之 String 數(shù)據(jù)結(jié)構(gòu)的讀寫
- 【DB 系列】Redis 之 Jedis 配置
- 【DB 系列】Redis 之基本配置
工程源碼
- 工程:https://github.com/liuyueyi/spring-boot-demo
- 項目源碼: https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/122-redis-template
1. 一灰灰 Blog
盡信書則不如,以上內(nèi)容谦去,純屬一家之言慷丽,因個人能力有限,難免有疏漏和錯誤之處哪轿,如發(fā)現(xiàn) bug 或者有更好的建議盈魁,歡迎批評指正,不吝感激
下面一灰灰的個人博客窃诉,記錄所有學習和工作中的博文,歡迎大家前去逛逛
- 一灰灰 Blog 個人博客 https://blog.hhui.top
- 一灰灰 Blog-Spring 專題博客 http://spring.hhui.top