日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網(wǎng)站首頁 編程語言 正文

Redis中HyperLogLog的使用詳情_Redis

作者:_燈火闌珊處 ? 更新時間: 2022-11-13 編程語言

前言

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

欄目分類
最近更新