版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zx711166/article/details/82855536
HyperLogLog是做什么的
- 基于HyperLogLog算法:极小空间完成独立数量统计,Redis中实现的HyperLogLog,只需要12K内存,在标准误差0.81%的前提下,能够统计 个数据。
- 本质还是字符串。
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
内存消耗 | |
---|---|
一天 | |
一个月 | |
一年 |
使用经验
- 是否能容忍错误率?(错误率:0.81%)
redis> pfcount 2016_05_01:unique:ids(integer)
1009838
- 是否需要单条数据?(无法获取单条数据)