深入Redis(四)HyperLogLog

HyperLogLog

如果负责开发维护一个大型网站,某天产品经理要每个网页每天的UV数据,对此开发一个统计模块,如何实现?

统计PV很容易,给每个网页一个独立的Redis计数器即可,这个计数器key后缀上当天的日期,来一个请求incrby一次,则可统计出所有的PV数据。

而UV不同,其需要去重,来自同一用户的多次访问只能计数一次,这要求每个请求都要带上用户id,无论是登陆用户还是未登陆用户都需要一个唯一id来标识。

  1. 首先想到的简单方案就是为每个页面提供一个独立的set来存储当天访问过此页面的用户id,来一个请求就sadd进去,通过scard来取出集合大小。
  2. 但是如果页面访问量特别大,就需要很多的空间来统计,而产品经理需要的数据不一定需要特别精确,Redis提供的HyperLogLog数据结构就是用来解决这种统计问题的,其提供不精确的去重统计方案,标准误差是0.81%。

使用方法

HyperLogLog提供两个指令,pfaddpfcount,用法和set的sadd是一样的,来一个用户id就放进去,pfcount的用法与scard用法也是一样的,直接获取计数值。

pf是什么意思?

pf是HyperLogLog这个数据结构的发明人Philippe Flajolet的首字母缩写。

pfmerge适合什么场合用?

HyperLogLog还提供了第三个指令pfmerge,用于将多个pf计数值累加在一起形成一个新的pf值。

例如两个内容差不多的页面数据进行合并,其中UV也要合并,则可以通过pfmerge来处理。

注意事项

HyperLogLog这个数据结构不是免费的,它需要占据一定的存储空间(12k),所以其不适合统计单个用户相关的数据,但相比用set的存储方案,HyperLogLog更完美。

另外,Redis对HyperLogLog的存储做了优化,在计数比较小时采用稀疏矩阵存储,空间占用很小,只有在计数变大,稀疏矩阵占用空间超过阈值才会一次性变为稠密矩阵,进而占用12k的空间。

实现原理

HyperLogLog的使用非常简单,但其实现原理比较复杂。

暂时略

pf的内存占用为什么是12k?

Redis的HyperLogLog视线中用到16384个桶,即2^14,每个桶的maxbits需要6个bits来存储,最大可以标识maxbits=63,于是2^14*6/8 = 12k。

原文地址:https://www.cnblogs.com/ikct2017/p/9499228.html

时间: 2024-08-30 13:28:55

深入Redis(四)HyperLogLog的相关文章

redis应用--HyperLogLog

如果你负责开发维护一个大型的网站,有一天老板找产品经理要网站每个网页每天的 UV 数据,然后让你来开发这个统计模块,你会如何实现? 如果统计 PV 那非常好办,给每个网页一个独立的 Redis 计数器就可以了,这个计数器的 key 后缀加上当天的日期.这样来一个请求,incrby 一次,最终就可以统计出所有的 PV 数据. 但是 UV 不一样,它要去重,同一个用户一天之内的多次访问请求只能计数一次.这就要求每一个网页请求都需要带上用户的 ID,无论是登陆用户还是未登陆用户都需要一个唯一 ID 来

Redis 四:存储类型之有序集合

有序集合似乎更大的操作是由于加了一个叫做“分子”的东西 事实上就好像普通的数据,只是为这个数据加了一个纯数字的标识, 通过操作这些标识来得到我们想要的数据! 分子可以是整形,也可以是双精度浮点型: ==================================================== 1.zadd num 100 a 80 b 70 c 添加一个叫num的有序集合,a元素为100分,b元素为80分.... 2.zscore num a 获取num集合中元素名为a的分子 ====

Redis 四:存储类型之无序集合

1.sadd num a b c 向num集合中添加abc三个元素 2.srem num b 从num集合中删除b元素 3.smembers num 获取num集合中所有的元素 4.sismember num c 判断c是否存在num集合中 ============================= 5.运算 sadd num a b c sadd num2 a b c d 差集(计算左边比右边多出来的那部分): sdiff num num 2 返回空 sdiff num2 num 返回d 交集

Redis 四:存储类型之散列类型

1.散列类型表达方式简介: =========================================== 键 字段 值 =========================================== 前轮 --->富士康 后轮 --->苹果 宝马: 挡风玻璃 --->加多宝 座椅 --->王老吉 方向盘 --->恒大冰泉 =========================================== 散列类型更好的作用于同一个对象,不同属性,对应不同

Redis 四:存储类型之列表类型

1.lpush num 0 1 2 3 4 5 6 7 8 9 10 依次从左边推入0 - 10 2.rpush num 0 1 2 3 4 5 6 7 8 9 10 依次从右边推入0 - 10 3.lrnage num 0 -1 显示num列表中所有的数据 结果:10 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9 10 4.lpop num 从左边删除并弹出一个元素 5.rpop num 从右边删除并弹出一个元素 6.llen num 获取元素个数 7.lra

Redis(四)-配置

Redis 配置 Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf. 你可以通过 CONFIG 命令查看或设置配置项. 语法 Redis CONFIG 命令格式如下: redis 127.0.0.1:6379> CONFIG GET CONFIG_SETTING_NAME 实例 redis 127.0.0.1:6379> CONFIG GET loglevel 1) "loglevel" 2) "notice" 使用 *

Redis命令-HyperLogLog

HyperLogLog数据结构简介 可以看http://www.cnblogs.com/ysuzhaixuefei/p/4052110.html  博客,介绍的相对比较清晰. HyperLogLog数据结构,可以接收多个参数输入,然后估算出元素的基数. ? 基数:集合中不同元素的数量.比如 {'apple', 'banana', 'cherry', 'banana', 'apple'} 的基数就是 3 . ? 估算值:算法给出的基数并不是精确的,可能会比实际稍微多一些或者稍微少一些,但会控制在合

Redis笔记- HyperLogLog

Redis 在 2.8.9 版本添加了 HyperLogLog 结构. Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的.并且是很小的. 在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数.这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比. 但是,因为 HyperLogLog 只会根据输入元素来计算

redis数据结构HyperLogLog

如果我们要实现记录网站每天访问的独立IP数量这样的一个功能 集合实现: 使用集合来储存每个访客的 IP ,通过集合性质(集合中的每个元素都各不相同)来得到多个独立 IP ,然后通过调用 SCARD 命令来得出独立 IP 的数量.举个例子,程序可以使用以下代码来记录 2014 年 8 月 15 日,每个网站访客的 IP :ip = get_vistor_ip()SADD '2014.8.15::unique::ip' ip然后使用以下代码来获得当天的唯一 IP 数量:SCARD '2014.8.1

Redis(四)——持久化方案(RDB和AOF使用)

一.持久化的作用 1.什么是持久化 redis的所有数据保存在内存中,对数据的更新将异步的保存到硬盘上 2.持久化的实现方式 快照:某时某刻数据的一个完成备份 -mysql的Dump -redis的RDB 写日志:任何操作记录日志,要恢复数据,只要把日志重新走一遍即可 -mysql的 Binlog -Hhase的 HLog -Redis的 AOF 二.RDB 1.什么是RDB 2.触发机制-主要三种方式 第一种: save(同步) 1 客户端输入save命令---->redis服务端---->