首頁 > 軟體

Redis中HyperLogLog的使用詳情

2022-09-26 14:06:18

前言

HyperLogLog ,基數統計;

那什麼是基數?

比如有兩個陣列

陣列A = [1,2,3,4,5];

陣列B = [3,4,5,6,7];

這時候基數就是 [1,2,3,4,5,6,7],總共有7個數;

就是去重之後的資料;

HyperLogLog 就是用來做去重複統計的;

bitmap 在做統計時,雖然使用的是 bit 來做記錄,已經很節省空間了;

但是在隨著資料量快速增長的情況下,bitmap 也是很佔記憶體空間的;

而 HyperLogLog 就不同了,HyperLogLog 的每個 key 只佔用 12kb 的記憶體,

就可以統計 2的64 次方個基數;

而且不會隨著資料量的增多而變大,就是固定的 12kb

這是因為 HyperLogLog 每次只會根據新增的資料去計算基數,而不儲存新增的資料本身;

但這也造成了一個問題,就是 HyperLogLog 基數統計的準確率不是100%,會有 0.81% 的誤差;

但對於億級資料的統計,這點誤差似乎可以忽略不計;

同樣的,bitmap 記錄資料本身,它的計算是精確的;

所有,也可以說 HyperLogLog 是一種概率計算,但是誤差是很小的。

這是reidis作者寫的關於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

重複資料不會被儲存,返回的是0

> pfadd 20220628:uv ip1 ip2 ip3
1
> pfadd 20220628:uv ip1 ip2 ip3
0
  • 獲取 HyperLogLog 的基數估算值
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 資料

然後再對 result 做 pfcount 操作

> pfcount result
8

這時候拿到的值就是 上面3個key 計算出來的基數。

HyperLogLog 在 spring 裡的使用也非常簡單,

pfadd 對應的是 .add() 操作;

pfcount 對應的是 .size() 操作;

pfmerge 對應的是 .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");

        // 獲取元素基數
        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);
    }
}

到此這篇關於Redis中HyperLogLog的使用詳情的文章就介紹到這了,更多相關RedisH yperLogLog內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com