Redis的数据结构之 HyperLogLogs

460 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第31天,点击查看活动详情

背景

项目中我们经常需要统计网页浏览的用户数量(一天内一个用户多次访问只能算一次)的需求,通常情况下我们可以使用Redis的Set的数据来进行统计,但是当用户的数据量非常大的时候,采用Set方式统计会对性能造成影响,那么还可以采用其他的方式来统计吗?我们可以采用Redis的HyperLogLogs来进行统计。

简介

Redis中的HyperLogLog是一种基于基数估算的算法,所谓基数估算就是在一批数据中不重复的元个数有多少个。HyperLogLog实际上不会存储每个元素的值,它使用的是概率算法,通过存储元素的hash值的第一个1的位置,来计算元素数量。而Redis的HyperLogLog统计2的64次方个数据,只需要12k的内存,且统计的标准误差在%0.18,非常适合于统计UV这种需求。

HyperLogLog算法原理

Redis的HyperLogLog是用来做基数统计的算法。

什么是基数

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

HyperLogLog公式

通过HyperLogLog算法是对于LogLog算法的改进,关于LogLog算法的具体实现,可以查询相关的资料进行了解, HyperLogLog的公式具体如下:

图片.png

说明:其中constant常数和m的含义和之前的LogLog算法公式中的含义一致,Rj代表(第j个桶中的数据的最大前导零数目+1),为了方便理解,我将公式再拆解一下:

图片.png

基本命令

图片.png

pfadd 添加元素

基本语法

pfadd key element

示例

图片.png

pfcount 返回给定HyperLogLog的基数估算值。

基本语法

pfcount key 

示例

图片.png

pfmerge 将多个HyperLogLog 合并为一个HyperLogLog

基本语法

pfmerge key1 key2

示例

图片.png

说明:集合hy1{2,3,4,5,6,7,8,9},集合hy2{0,10,14,15,6,7,8,19} 合并后的集合为:{2,3,4,5,6,7,8,9,14,15,0,10,19}所以长度为13.

应用场景

  • 统计每日访问IP数
  • 统计页面实时UV数
  • 统计在线用户数
  • 统计用户每天搜索不同词条的个数

总结

本文讲解了Redis的HyperLogLogs的数据结构和相关的命令,HyperLogLogs是基于基数估算的算法,所以估计统计会存在误差,而通过Set来进行统计根据准确,但需要考虑性能,所以我们需要在不同的业务场景需要选择合适的Redis的数据结构进行存储。