用户日活月活怎么统计 - Redis HyperLogLog 详解

HyperLogLog

提出问题

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

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

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

如果访问量很大,需要涉及很多数据的存储、去重,内存消耗很大。

Set自不必说,消耗很好。bitmap相比于Set也大大节省了内存,我们来粗略计算一下,统计1亿个数据的基数,需要的内存是:100000000/8/1024/1024 ≈ 12M。当数据量上去了,还是会消耗很大。

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

概念

HyperLogLog 是一种概率数据结构,用来估算数据的基数。数据集可以是网站访客的 IP 地址,E-mail 邮箱或者用户 ID。

基数就是指一个集合中不同值的数目,比如 a, b, c, d 的基数就是 4,a, b, c, d, a 的基数还是 4。虽然 a 出现两次,只会被计算一次。

Redis 的 HyperLogLog 通过牺牲准确率来减少内存空间的消耗,只需要12K内存,在标准误差0.81%的前提下,能够统计2^64个数据。所以 HyperLogLog 是否适合在比如统计日活月活此类的对精度要不不高的场景。

HyperLogLog 在 Redis 中的使用

Redis 提供了 PFADDPFCOUNTPFMERGE 三个命令来供用户使用 HyperLogLog。

PFADD 用于向 HyperLogLog 添加元素。

> PFADD visitors alice bob carol
(integer) 1
> PFCOUNT visitors
(integer) 3

如果 HyperLogLog 估计的近似基数在 PFADD 命令执行之后出现了变化, 那么命令返回 1 , 否则返回 0 。 如果命令执行时给定的键不存在, 那么程序将先创建一个空的 HyperLogLog 结构, 然后再执行命令。

PFCOUNT 命令会给出 HyperLogLog 包含的近似基数。在计算出基数后,PFCOUNT 会将值存储在 HyperLogLog 中进行缓存,知道下次 PFADD 执行成功前,就都不需要再次进行基数的计算。

PFMERGE 将多个 HyperLogLog 合并为一个 HyperLogLog , 合并后的 HyperLogLog 的基数接近于所有输入 HyperLogLog 的并集基数。

> PFADD customers alice dan
(integer) 1
> PFMERGE everyone visitors customers
OK
> PFCOUNT everyone
(integer) 4

基本原理

原文。

Redis其他数据结构的更多相关文章

  1. Redis基本数据结构总结之STRING和LIST

    Redis基本数据结构总结前言 Redis的特点在于其读写速度特别快,因为是存储在内存中的,其非常适合于处理大数据量的情况:还有一个是其不同于其他的关系型数据库,Redis是非关系型数据库,也就是我们 ...

  2. Redis基本数据结构总结之SET、ZSET和HASH

    Redis基本数据结构总结 前言 Redis的特点在于其读写速度特别快,因为是存储在内存中的,其非常适合于处理大数据量的情况:还有一个是其不同于其他的关系型数据库,Redis是非关系型数据库,也就是我 ...

  3. Redis各种数据结构性能数据对比和性能优化实践

    很对不起大家,又是一篇乱序的文章,但是满满的干货,来源于实践,相信大家会有所收获.里面穿插一些感悟和生活故事,可以忽略不看.不过听大家普遍的反馈说这是其中最喜欢看的部分,好吧,就当学习之后轻松一下. ...

  4. 聊一聊Redis的数据结构

    如果没有记错的话,应该是在两个月前把 我们经常看到此类的文章: Redis的五种数据结构 Redis的数据结构以及对应的使用场景 其实以数据结构这个词去说明Redis的String.Hash.List ...

  5. Redis学习——数据结构介绍(四)

    一.简介 作为一款key-value 的NoSQL数据库,Redis支持的数据结构比较丰富,有:String(字符串) .List(列表) .Set(集合) .Hash(哈希) .Zset(有序集合) ...

  6. Redis常用数据结构

    Redis常用数据结构包括字符串(strings),列表(lists),哈希(hashes),集合(sets),有序集合(sorted sets). redis的key最大不能超过512M,可通过re ...

  7. Redis的数据结构、通用操作及其特性

    Redis的数据结构 五种数据类型: 字符串(String).字符串列表(list).字符串集合(set).有序字符串集合(sorted set).哈希(hash) key定义的注意点: 不要过长,不 ...

  8. Redis学习笔记之Redis基本数据结构

    Redis基础数据结构 Redis有5种基本数据结构:String(字符串).list(列表).set(集合).hash(哈希).zset(有序集合) 字符串string 字符串类型是Redis的va ...

  9. 你真的懂redis的数据结构了吗?redis内部数据结构和外部数据结构揭秘

    Redis有哪些数据结构? 字符串String.字典Hash.列表List.集合Set.有序集合SortedSet. 很多人面试时都遇到过这种场景吧? 其实除了上面的几种常见数据结构,还需要加上数据结 ...

  10. Redis的数据结构

    Redis的数据结构 redis是一种高级的key-value的存储系统,其中value支持五种数据类型. 字符串(String) 哈希(hash) 字符串列表(list) 字符串集合(set) 有序 ...

随机推荐

  1. 软件定义网络基础---SDN的核心思想

    一:SDN包含的核心思想:解耦,抽象,可编程 二:解耦 (一)SDN网络解耦思想 解耦是指将控制平面和数据平面进行分离,主要为了解决传统网络中控制平面和数据平面在物理上紧耦合导致的问题 控制平面和数据 ...

  2. Linux的桌面虚拟化技术KVM(二)——远程桌面管理

    Linux的桌面虚拟化技术KVM(一)——新建KVM虚拟机 远程桌面管理,指的是远程图形界面管理,所以要保证物理机要有图形化界面. (1).VNC管理 安装VNC-server服务,并进行配置 [ro ...

  3. iOS textFiledView,label自适应高度

    CGSize constraintSize; constraintSize.width = 320; constraintSize.height = MAXFLOAT; CGSize sizeFram ...

  4. layui select渲染获取选中的option

    关键代码如下: form.on('select(groupCode)', function(data){ console.log($(data.elem).find("option:sele ...

  5. WINDOWS配置WSUS。

    wsus的注册表文件! Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINESOFTWAREPoliciesMicrosoftWindows ...

  6. ubuntu 18.04下载mysql8.0.13源码并编译安装(暂时没有成功)

    执行如下命令下载解压MySQL8的源码文件压缩包到本地文件: wget https://cdn.mysql.com//Downloads/MySQL-8.0/mysql-boost-8.0.13.ta ...

  7. httpsqs消息队安装

    HTTPSQS(HTTP Simple Queue Service)是一款基于 HTTP GET/POST 协议的轻量级开源简单消息队列服务,使用 Tokyo Cabinet 的 B+Tree Key ...

  8. PHP比较两个版本的方法

    PHP比较两个版本的方法 写app接口经常要用到 PHP接口的版本和app里面的版本做比较 如果app版本低于接口版本 那么就要提示他升级 <pre><?php/** * 版本处理类 ...

  9. ubuntu下安装chrome浏览器和flash插件

    chrome浏览器可在Ubuntu软件中心里搜索并安装 falsh插件首先去官网下载合适的包然后,按照readme安装,执行sudo cp -r usr/* /usr 和sudo cp libflas ...

  10. scrapy工具创建爬虫工程

    1.scrapy创建爬虫工程:scrapy startproject scrape_project_name >scrapy startproject books_scrapeNew Scrap ...