Redis HyperLogLog命令

Redis HyperLogLog命令教程

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。

Redis HyperLogLog优点

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定的、并且是很小的。

在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 264 个不同元素的基数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。

但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像 集合 那样,返回输入的各个元素。

什么是基数?

比如数据集 {1, 3, 5, 7, 5, 7, 8}, 那么这个数据集的基数集为 {1, 3, 5 ,7, 8} ,基数(不重复元素)为 5。 基数估计就是在误差可接受的范围内,快速计算基数。

简单原理

HyperLogLog 是 Probabilistic data Structures 的一种,这类数据结构的基本大的思路就是使用统计概率上的算法,牺牲数据的精准性来节省内存的占用空间及提升相关操作的性能。

使用场景

我们思考一个常见的业务问题:如果你负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的 UV 数据,然后让你来开发这个统计模块,你会如何实现?

如果统计 PV 那非常好办,给每个网页一个独立的 Redis 计数器就可以了,这个计数器的 key 后缀加上当天的日期。这样来一个请求,incrby 一次,最终就可以统计出所有的 PV 数据。

但是 UV 不一样,它要去重,同一个用户一天之内的多次访问请求只能计数一次。这就要求每一个网页请求都需要带上用户的 ID,无论是登陆用户还是未登陆用户都需要一个唯一 ID 来标识。

你也许已经想到了一个简单的方案,那就是为每一个页面一个独立的 set 集合来存储所有当天访问过此页面的用户 ID。当一个请求过来时,我们使用 sadd 将用户 ID 塞进去就可以了。通过 scard 可以取出这个集合的大小,这个数字就是这个页面的 UV 数据。没错,这是一个非常简单的方案。

但是,如果你的页面访问量非常大,比如一个爆款页面几千万的 UV,你需要一个很大的 set 集合来统计,这就非常浪费空间。如果这样的页面很多,那所需要的存储空间是惊人的。为这样一个去重功能就耗费这样多的存储空间,值得么?其实老板需要的数据又不需要太精确,105w 和 106w 这两个数字对于老板们来说并没有多大区别,So,有没有更好的解决方案呢?

这就是我们需要引入的一个解决方案,Redis 提供了 HyperLogLog 数据结构就是用来解决这种统计问题的。HyperLogLog 提供不精确的去重计数方案,虽然不精确但是也不是非常不精确,标准误差是 0.81%,这样的精确度已经可以满足上面的 UV 统计需求了。

常用命令

命令 描述
PFADD KEY element [element …] 添加指定元素到 HyperLogLog 中。
PFCOUNT KEY [KEY …] 返回给定 HyperLogLog 的基数估算值。
PFMERGE destKEY sourceKEY [sourceKEY …] 将多个 HyperLogLog 合并为一个 HyperLogLog。

案例

192.168.98.70:6379> PFADD haicoder Redis (integer) 1 192.168.98.70:6379> PFADD haicoder Mongo (integer) 1 192.168.98.70:6379> PFADD haicoder Mysql (integer) 1 192.168.98.70:6379> PFCOUNT haicoder (integer) 3 192.168.98.70:6379> DEL haicoder (integer) 1

我们首先,使用 PFADD 命令向键 haicoder 的 HyperLogLog 中插入元素 Redis。使用 PFADD 命令向键 haicoder 的 HyperLogLog 中插入元素 Mongo。

接着,我们使用 PFADD 命令向键 haicoder 的 HyperLogLog 中插入元素 Mysql。最后,我们使用 PFCOUNT 命令获取键 haicoder 的 HyperLogLog 的元素数量。

Redis HyperLogLog命令总结

Redis 在 2.8.9 版本添加了 HyperLogLog 结构。

Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。