企业级Redis开发运维从入门到实践 (13)— HyperLogLog

HyperLogLog是做什么的
  1. 基于HyperLogLog算法:极小空间完成独立数量统计,Redis中实现的HyperLogLog,只需要12K内存,在标准误差0.81%的前提下,能够统计 2 64 2^{64} 264个数据。
  2. 本质还是字符串。
redis> type hyperloglog_key
string
redis中hyperloglog实现

Redis正是基于HyperLogLog Counting(HLL)算法实现的HyperLogLog结构,用于统计一组数据集合中不重复的数据个数。

Redis中统计数组大小设置为,hash函数生成64位bit数组,其中用来找到统计数组的位置,剩下50位用来记录第一个1出现的位置,最大位置为50,需要记录。

那么统计数组需要的最大内存大小为: 基数估计的标准误差位。

HyperLogLog的相关命令
pfadd
  • pfadd key element [element …]:向hyperloglog添加元素。
  • 时间复杂度:每添加一个元素的复杂度为 O(1) 。
  • 如果给定键已经是一个 HyperLogLog , 那么这种调用不会产生任何效果。
  • 但如果给定的键不存在, 那么命令会创建一个空的 HyperLogLog , 并向客户端返回 1 。
# 返回值:整数回复,如果 HyperLogLog 的内部储存被修改了, 那么返回 1 , 否则返回 0 。
redis> pfadd 2017_03_06:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4"
(integer) 1
pfcount
  • pfcount key [key …]:计算hyperloglog的独立总数。
  • 时间复杂度:当命令作用于单个 HyperLogLog 时, 复杂度为 O(1) , 并且具有非常低的平均常数时间。 当命令作用于 N 个 HyperLogLog 时, 复杂度为 O(N) , 常数时间也比处理单个 HyperLogLog 时要大得多。
redis> pfcount 2017_03_06:unique:ids
(integer) 4

redis> pfadd 2017_03_06:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-90"
(integer) 1

redis> pfcount 2017_03_06:unique:ids
(integer) 5
pfmerge
  • pfmerge destkey sourcekey [sourcekey …]:合并多个hyperloglog。
  • 时间复杂度:O(N) , 其中 N 为被合并的 HyperLogLog 数量, 不过这个命令的常数复杂度比较高。
# 添加 key 是 2016_03_06:unique:ids
redis> pfadd 2016_03_06:unique:ids "uuid-1" "uuid-2" "uuid-3" "uuid-4"
(integer) 1
redis> pfcount 2016_03_06:unique:ids
(integer) 5

#添加 key 是 2016_03_05:unique:ids
redis> pfadd 2016_03_05:unique:ids "uuid-4" "uuid-5" "uuid-6" "uuid-7"
(integer) 1
redis> pfcount 2016_03_05:unique:ids
(integer) 4

# 合并 2016_03_06:unique:ids、2016_03_05:unique:ids
redis> pfmerge 2016_03_05_06:unique:ids 2016_03_05:unique:ids 2016_03_06:unique:ids
OK
reids> pfcount 2016_03_05_06:unique:ids
(integer) 7
内存消耗(百万独立用户)
elements = ""
key = "2016_05_01:unique:ids"
for i in 'seq 1 1000000'
do
	elements = "${elements} uuid-"${i}
	if [[ $((i%1000)) == 0 ]]
	then
		redis-cli pfadd ${key} ${elements}
		elements = ""
	fi
done
内存消耗
一天 15 K B 15KB 15KB
一个月 15 K B ∗ 30 = 450 K B 15KB*30 = 450KB 15KB30=450KB
一年 15 K B ∗ 365 ≈ 5 M B 15KB*365 \approx 5MB 15KB3655MB
使用经验
  1. 是否能容忍错误率?(错误率:0.81%)
redis> pfcount 2016_05_01:unique:ids(integer)
1009838
  1. 是否需要单条数据?(无法获取单条数据)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值