網(wǎng)站首頁 編程語言 正文
前言
HyperLogLog?,基數(shù)統(tǒng)計;
那什么是基數(shù)?
比如有兩個數(shù)組
數(shù)組A = [1,2,3,4,5];
數(shù)組B = [3,4,5,6,7];
這時候基數(shù)就是?[1,2,3,4,5,6,7],總共有7個數(shù);
就是去重之后的數(shù)據(jù);
HyperLogLog?就是用來做去重復(fù)統(tǒng)計的;
bitmap?在做統(tǒng)計時,雖然使用的是?bit?來做記錄,已經(jīng)很節(jié)省空間了;
但是在隨著數(shù)據(jù)量快速增長的情況下,bitmap?也是很占內(nèi)存空間的;
而?HyperLogLog?就不同了,HyperLogLog?的每個?key?只占用?12kb?的內(nèi)存,
就可以統(tǒng)計?2的64?次方個基數(shù);
而且不會隨著數(shù)據(jù)量的增多而變大,就是固定的?12kb;
這是因為?HyperLogLog?每次只會根據(jù)添加的數(shù)據(jù)去計算基數(shù),而不保存添加的數(shù)據(jù)本身;
但這也造成了一個問題,就是?HyperLogLog?基數(shù)統(tǒng)計的準確率不是100%,會有?0.81%?的誤差;
但對于億級數(shù)據(jù)的統(tǒng)計,這點誤差似乎可以忽略不計;
同樣的,bitmap?記錄數(shù)據(jù)本身,它的計算是精確的;
所有,也可以說?HyperLogLog?是一種概率計算,但是誤差是很小的。
這是reidis作者寫的關(guān)于HyperLogLog的文章
HyperLogLog?的使用也非常簡單,就3個操作api
添加元素
pfadd key value [value ...]
pfadd 20220628:uv ip1 ip2 ip3
pfadd 20220629:uv ip1 ip2 ip3 ip4 ip5
pfadd 20220630:uv ip2 ip4 ip5 ip6 ip7 ip8
重復(fù)數(shù)據(jù)不會被保存,返回的是0
> pfadd 20220628:uv ip1 ip2 ip3
1
> pfadd 20220628:uv ip1 ip2 ip3
0
- 獲取 HyperLogLog 的基數(shù)估算值
PFCOUNT key [key ...]
> pfcount 20220628:uv 20220629:uv
5
合并得出的不會被儲存,使用之后就會被刪掉
- 合并多個key
pfmerge destkey key [key ...]
> pfmerge result 20220628:uv 20220629:uv 20220630:uv
OK
pfmerge?合并多個key后,會生成一條 result 數(shù)據(jù)
然后再對 result 做 pfcount 操作
> pfcount result
8
這時候拿到的值就是 上面3個key 計算出來的基數(shù)。
HyperLogLog?在?spring?里的使用也非常簡單,
pfadd?對應(yīng)的是?.add()?操作;
pfcount?對應(yīng)的是?.size()?操作;
pfmerge?對應(yīng)的是?.union()?操作;
下面是使用的?Demo
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.HyperLogLogOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
@SpringBootTest
@RunWith(SpringRunner.class)
class RedisTest {
@Resource
private RedisTemplate<String, String> redisTemplate;
@Test
void hyperLogLogTest() {
HyperLogLogOperations<String, String> hyperLogLogOperations = redisTemplate.opsForHyperLogLog();
// 添加元素
Long add = hyperLogLogOperations.add("20220628:uv", "ip1", "ip2", "ip3");
System.out.println("add : " + add);
hyperLogLogOperations.add("20220629:uv", "ip1", "ip2", "ip3", "ip4", "ip5");
hyperLogLogOperations.add("20220630:uv", "ip2", "ip4", "ip5", "ip6", "ip7", "ip8");
// 獲取元素基數(shù)
Long size = hyperLogLogOperations.size("20220628:uv", "20220629:uv");
System.out.println("size : " + size);
// 合并多個元素
Long result = hyperLogLogOperations.union("unionResult", "20220628:uv", "20220629:uv", "20220630:uv");
System.out.println("result : " + result);
Long unionResult = hyperLogLogOperations.size("unionResult");
System.out.println("unionResult : " + unionResult);
}
}
原文鏈接:https://juejin.cn/post/7114915981671006221
相關(guān)推薦
- 2024-03-06 Maven終端命令生成Spring-boot項目并輸出“helloworld“
- 2022-05-11 Python學習之私有函數(shù),私有變量及封裝詳解_python
- 2022-07-15 初識python的numpy模塊_python
- 2024-03-07 SpringIoC-基于XML配置方式組件管理
- 2023-02-17 Go語言Gin處理響應(yīng)方式詳解_Golang
- 2022-12-07 進程狀態(tài)ps?-ef中的e、f含義講解_linux shell
- 2023-01-18 React?Fiber?樹思想解決業(yè)務(wù)實際場景詳解_React
- 2022-09-21 Android開發(fā)之AAR文件的生成與使用步驟_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細win安裝深度學習環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支