Redis HyperLogLog 数据结构模型统计

HyperLogLog

HyperLogLog 不是一种新的数据结构 , 本质上是字符串类型。 是一种基数算法。 通过 HyperLogLog 可以节省内存空间,并完成独立总数的统计。

HyperLogLog 数据结构可用于仅使用少量恒定内存来计算集合中的唯一元素,具体而言,每个 HyperLogLog 为 12k 字节(加上键本身的几个字节)。

HyperLogLog 相关命令:

  • PFADD: 将所有元素参数添加到存储在作为第一个参数指定的变量名中的HyperLogLog数据结构中。
  • PFCOUNT: 使用单个键调用时,返回存储在指定变量处的HyperLogLog数据结构计算的近似基数,如果该变量不存在,则返回0。
  • PFDEBUG:是一个内部命令。它是用来开发和测试Redis的。
  • PFMERGE: 将多个HyperLogLog值合并为一个唯一的值,该值将近似于源HyperLogLog结构的观察集的并集的基数。
  • PFSELFTEST: 是一个内部命令。它是用来开发和测试Redis的。

PFADD

添加元素,复杂度 O(1), 用于向 HyperLogLog 添加 元素 , 如果成功返回 1 :

PFADD key [element [element ...]]

向 键 2023_12-11:user 添加 元素

192.168.88.11:6380> PFADD 2023_12-11:user "user1" "user2" "user3" "user4" "user5" "user6"
(integer) 1

192.168.88.11:6380> PFADD 2023_12-12:user "user1" "user3" "user5" "user7" "user8" "user9"
(integer) 1

HyperLogLog 不是一种新的数据结构 , 本质上是字符串类型。 HyperLogLog 是一个 Redis 字符串,可以使用 GET 检索 和 SET 恢复。

192.168.88.11:6380> type 2023_12-11:user
string

192.168.88.11:6380> get 2023_12-11:user
"HYLL\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80WR\x80F\x19\x80E\xed\x8cF\x10\x84N\x92\x80@\xfc\x80F\xfd"

192.168.88.11:6380> type 2023_12-12:user
string

192.168.88.11:6380> get 2023_12-12:user
"HYLL\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x80WR\x80F\x19\x80[\x91\x80B\xb9\x8cA\x7f\x84Ab\x88A]"

PFCOUNT

用于计算一个或多个HyperLogLog的独立总数, 当使用单个键调用时,复杂度 O(1),平均时间非常小。当调用多个键时,复杂度O(N),其中N是键的个数,时间要大得多。

如: 计算 2023_12-11:user 、 2023_12-12:user 的独立总数

192.168.88.11:6380> PFCOUNT 2023_12-11:user
(integer) 6

192.168.88.11:6380> PFCOUNT 2023_12-12:user
(integer) 6

往 2023_12-11:user 、 2023_12-12:user 插入新的元素:

192.168.88.11:6380> PFADD 2023_12-11:user "user10" "user11"
(integer) 1

192.168.88.11:6380> PFADD 2023_12-12:user "user15" "user16" "user20" "user21"
(integer) 1

再次 计算 2023_12-11:user 、 2023_12-12:user 的独立总数

192.168.88.11:6380> PFCOUNT 2023_12-11:user
(integer) 8

192.168.88.11:6380> PFCOUNT 2023_12-12:user
(integer) 10

计算 两个键 2023_12-11:user 、 2023_12-12:user 的独立总数 (3个重复用户: user1、user3、user5)
在这里插入图片描述

当使用多个键调用时,通过在内部将存储在提供键处的HyperLogLog合并为临时HyperLogLog,返回传递的HyperLogLog联合的近似基数。

返回的观察集基数并不精确,而是近似值,标准误差为 0.81%。

当PFCOUNT使用多个键调用时,会执行 HyperLogLogs 的即时合并,这很慢,而且联合的基数无法缓存,因此当使用多个键时PFCOUNT可能需要大约时间毫秒级,不应滥用。

192.168.88.11:6380> PFCOUNT 2023_12-11:user 2023_12-12:user 
(integer) 15

PFMERGE

pfmerge 可以合并多个 HyperLogLog的并集赋值给 destkey

将多个 HyperLogLog 值合并为一个唯一值,该值将近似观察到的源 HyperLogLog 结构集的并集基数。

计算出的合并 HyperLogLog 设置为目标变量,如果不存在则创建该变量(默认为空 HyperLogLog)。

如合并 两个键 2023_12-11:user 、 2023_12-12:user 的独立总数:

192.168.88.11:6380> PFMERGE 2023_12-11-12:user  2023_12-11:user 2023_12-12:user
OK

192.168.88.11:6380> PFCOUNT 2023_12-11-12:user
(integer) 15

Memory

分别向 HyperLogLog、 Set 插入10万个 用户,并对比内存使用量,如下:

  • 插入 10 万用户到 HyperLogLog:2023_12:users
192.168.88.11:6380> eval "for i=1,100000\ndo\n  redis.call('pfadd', 'HyperLogLog:2023_12:users', 'user'..i)\nend\n" 0 
(nil)
(0.63s)

# 返回的观察集基数并不精确,而是近似值,  即 : 99725/100000=99.7%, 误差: 0.27% 
192.168.88.11:6380> PFCOUNT HyperLogLog:2023_12:users
(integer) 99725

# 内存使用量 12KB
192.168.88.11:6380> MEMORY USAGE HyperLogLog:2023_12:users
(integer) 12377
  • 同样插入 10 万用户到 Set:2023_12:users
192.168.88.11:6380> eval "for i=1,100000\ndo\n  redis.call('sadd', 'Set:2023_12:users', 'user'..i)\nend\n" 0 
(nil)
(0.74s)

# 数量精确
192.168.88.11:6380> SCARD Set:2023_12:users
(integer) 100000

# 内存使用量 4.8MB 
192.168.88.11:6380> MEMORY USAGE Set:2023_12:users
(integer) 5033019

小结

  • HyperLogLog 数据结构可用于仅使用少量恒定内存来计算集合中的唯一元素, 内存占用非常小。 但是存在错误率。
  • 可以容忍一定的错误率,返回的观察集基数并不精确,而是近似值,标准误差为 0.81%。
  • 只是想统计独立总数、而不需要获取具体的单条数据。

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2023-12-14 17:04:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-14 17:04:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-14 17:04:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-14 17:04:02       20 阅读

热门阅读

  1. 矩阵的相似标准型1

    2023-12-14 17:04:02       26 阅读
  2. 【点云异常点检测】MVTec AD数据集介绍

    2023-12-14 17:04:02       36 阅读
  3. PID算法

    PID算法

    2023-12-14 17:04:02      28 阅读
  4. solidity 整数溢出漏洞

    2023-12-14 17:04:02       38 阅读
  5. LinuxBasicsForHackers笔记 -- 了解和检查无线网络

    2023-12-14 17:04:02       44 阅读
  6. Moonbeam与Subsocial集成,为网络带来社交应用创建

    2023-12-14 17:04:02       36 阅读
  7. maui sqlite开发一个商城加购物车的演示(2)

    2023-12-14 17:04:02       34 阅读
  8. Linux - 内存 - memblock 分配器

    2023-12-14 17:04:02       38 阅读
  9. Linux 创建一个service并设置开机启动

    2023-12-14 17:04:02       47 阅读
  10. Springboot+Libreoffice集成开发

    2023-12-14 17:04:02       41 阅读
  11. springboot_3.2_freemark_基础环境配置

    2023-12-14 17:04:02       36 阅读
  12. Cmake

    2023-12-14 17:04:02       38 阅读