Redis中HyperLogLog的使用详情

目录
  • 前言
  • 添加元素

前言

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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Redis高级数据类型Hyperloglog、Bitmap的使用

    前言 很多小伙伴在面试中都会被问道 Redis的常用数据结构有哪些? 可能很大一部分回答都是 string.hash.list.set.zset.当然啦,这个答案肯定是没有错的,但是相信这个答案,面试官已经听的耳朵都起茧了. 本身我们选择的这个行业竞争就极强,学历拼不过难道还要知识都拼不过吗??? 希望进来的小伙伴能好好看完这篇文章,也希望你以后的回答能是 常用的数据结构有string.hash.list.set.zset,但我平时可能还会用到 Hyperloglog和Bitmap.相信面试官听

  • Redis中3种特殊的数据类型(BitMap、Geo和HyperLogLog)

    前言 Reids 在 Web 应用的开发中使用非常广泛,几乎所有的后端技术都会有涉及到 Redis 的使用.Redis 种除了常见的字符串 String.字典 Hash.列表 List.集合 Set.有序集合 SortedSet 等等之外,还有一些不常用的数据类型,这里着重介绍三个.下面话不多说了,来一起看看详细的介绍吧. BitMap BitMap 就是通过一个 bit 位来表示某个元素对应的值或者状态, 其中的 key 就是对应元素本身,实际上底层也是通过对字符串的操作来实现.Redis 从

  • Redis如何使用HyperLogLog的实现

    目录 1. 概述 2. 什么是基数? 3. 命令 3.1 PFADD 3.2 PFCOUNT 3.3 PFMERGE 1. 概述 Redis 在 2.8.9 版本添加了 HyperLogLog 数据结构,用来做基数统计,其优点是在输入元素的数量非常大时,计算基数所需的空间比较小并且一般比较恒定. 在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存就可以计算接近 2^64 个不同元素的基数.这和计算基数时,元素越多耗费内存越多的集合形成鲜明对比.但是,因为 Hype

  • Redis特殊数据类型HyperLogLog基数统计算法讲解

    目录 Redis HyperLogLog基数统计 一.pfadd 二.pfcount 三.pfmerge Redis HyperLogLog基数统计 HyperLogLog 是用来做基数统计的算法. 先了解下什么是基数. 比如数据集{1, 3, 5, 7, 5, 7, 8},那么这个数据集的基数集为{1, 3, 5 ,7, 8},基数(不重复元素)为5. 如果,现在需要统计一下网页的UV,那么就会涉及到去重了,这种场景就很适合用HyperLogLog. 这不就是set集合嘛?我用set来得出不重

  • Redis中HyperLogLog的使用详情

    目录 前言 添加元素 前言 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 就不同了,Hy

  • C# .NET 中的缓存实现详情

    目录 一.缓存的基本概念 二.缓存 三.进程内缓存早期做法 四.更好的解决方案 1. Microsoft.Extensions.Caching.Memory 2.具有驱逐策略的 IMemoryCache 3.问题和缺失的功能 4.代码说明 五.何时使用 WaitToFinishMemoryCache 一.缓存的基本概念 缓存 .这是一个简单但非常有效的概念,这个想法的核心是记录过程数据,重用操作结果.当执行繁重的操作时,我们会将结果保存在我们的 缓存容器中 .下次我们需要该结果时,我们将从缓存容

  • Redis主从复制操作和配置详情

    目录 前言 一.Redis-server环境变量 二.配置集群的Redis.conf 三.配置主从服务器 四.启动三台Redis服务器 前言 环境:CentOS7下安装Redis集群,默认已安装好5.0及以上版本,操作包括: Redis-server环境变量 配置配置集群的 Redis.confRedis主从配置和启动 测试主从机的数据一致性和读写分离 一.Redis-server环境变量 启动redis服务报错: -bash: redis-server: command not found 原

  • redis中事务机制及乐观锁的实现

    Redis事务机制 在MySQL等其他数据库中,事务表示的是一组动作,这组动作要么全部执行,要么全部不执行. Redis目前对事物的支持相对简单.Redis只能保证一个client发起的事务中的命令可以连续的执行,而中间不会插入其他的client命令.当一个client在一个链接中发出multi命令时,这个链接会进入一个事务上下文,该连接后续的命令不会立即执行,而是先放到一个队列中,当执行exec命令时,redis会顺序的执行队列中的所有命令. Multi 开启事务: 127.0.0.1:637

  • Redis中5种数据结构的使用场景介绍

    一.redis 数据结构使用场景 原来看过 redisbook 这本书,对 redis 的基本功能都已经熟悉了,从上周开始看 redis 的源码.目前目标是吃透 redis 的数据结构.我们都知道,在 redis 中一共有5种数据结构,那每种数据结构的使用场景都是什么呢? String--字符串 Hash--字典 List--列表 Set--集合 Sorted Set--有序集合 下面我们就来简单说明一下它们各自的使用场景: 1. String--字符串 String 数据结构是简单的 key-

  • 详解Redis中的双链表结构

    Redis中双链表实现的基本结构: 1.节点结构 typedef struct listNode { struct listNode *prev; //前向节点 struct listNode *next; //后向节点 void *value; //该节点的值 } listNode; 2.双向链表结构 typedef struct list { listNode *head; //头节点 listNode *tail; //尾节点 void *(*dup)(void *ptr); //复制函数

  • redis中使用java脚本实现分布式锁

    redis被大量用在分布式的环境中,自然而然分布式环境下的锁如何解决,立马成为一个问题.例如我们当前的手游项目,服务器端是按业务模块划分服务器的,有应用服,战斗服等,但是这两个vm都有可能同时改变玩家的属性,这如果在同一个vm下面,就很容易加锁,但如果在分布式环境下就没那么容易了,当然利用redis现有的功能也有解决办法,比如redis的脚本. redis在2.6以后的版本中增加了Lua脚本的功能,可以通过eval命令,直接在RedisServer环境中执行Lua脚本,并且可以在Lua脚本中调用

  • .NET客户端实现Redis中的管道(PipeLine)与事物(Transactions)

    序言 Redis中的管道(PipeLine)特性:简述一下就是,Redis如何从客户端一次发送多个命令,服务端到客户端如何一次性响应多个命令. Redis使用的是客户端-服务器模型和请求/响应协议的TCP服务器,这就意味着一个请求要有以下步骤才能完成:1.客户端向服务器发送查询命令,然后通常以阻塞的方式等待服务器相应.2.服务器处理查询命令,并将相应发送回客户端.这样便会通过网络连接,如果是本地回环接口那么就能特别迅速的响应,但是如果走外网,甚至外网再做一系列的层层转发,那就显的格外蛋疼.无论网

  • Redis中的动态字符串学习教程

    sds 的用途 Sds 在 Redis 中的主要作用有以下两个: 实现字符串对象(StringObject): 在 Redis 程序内部用作 char* 类型的替代品: 以下两个小节分别对这两种用途进行介绍. 实现字符串对象 Redis 是一个键值对数据库(key-value DB), 数据库的值可以是字符串.集合.列表等多种类型的对象, 而数据库的键则总是字符串对象. 对于那些包含字符串值的字符串对象来说, 每个字符串对象都包含一个 sds 值. "包含字符串值的字符串对象",这种说

随机推荐