在 AnalyticDB for PostgreSQL 中使用HyperLogLog 实现毫秒级 UV / PV 统计

本文涉及的产品
阿里云百炼推荐规格 ADB PostgreSQL,4核16GB 100GB 1个月
RDS PostgreSQL Serverless,0.5-4RCU 50GB 3个月
推荐场景:
对影评进行热评分析
简介: 在互联网产品的日常运营中, 经常需要统计产品的日活/月活用户量. 本文介绍了在[分析型数据库PostgreSQL版](https://common-buy.aliyun.com/?commodityCode=GreenplumPre&aly_as=tQHn1Vqa#/buy)中如何使用HyperLogLog扩展来完成日活/月活用户量的统计.

在互联网产品的日常运营中, 经常需要统计网页的 PV / UV 访问量,或者产品的 日活/月活 用户量. 本文介绍了在分析型数据库PostgreSQL版中如何使用HyperLogLog扩展来完成PV/UV 或者 日活/月活用户量的统计. 该方法能在误差不超过千分之二的前提下将统计时间降低300倍以上.

HyperLogLog 是一种算法, 可以用来估算数据集的基数. 基数是指一个集合中不同值的数目, 等同于 COUNT(DISTINCT field) 返回值. 对于超大数据集来说, 精确的基数统计往往需要消耗大量的内存与时间, 并且消耗的内存与时间会随着数据集基数的增加而成比例增加. 而 HyperLogLog 能够在常数级的内存与时间下, 以极低的误差来获取数据集基数的近似统计. 在分析型数据库PostgreSQL版中, HyperLogLog 的误差与内存消耗量受如下参数控制:

  • log2m, 该参数控制着 HyperLogLog 对数据集基数估算的误差为: 1.04 / math.sqrt(2 ** log2m). 该参数同时也控制着 HyperLogLog 内存消耗量.
  • regwidth, 该参数与 log2m 一起决定了 HyperLogLog 内存消耗量最多为 (2 ** log2m) * regwidth / 8 字节. 同时该函数也决定了 HyperLogLog 所能估算数据集基数的最大值.

本文在演示时, log2m 参数取值为 17, regwidth 参数取值为 7. 此时 HyperLogLog 对数据集基数估算的误差为千分之二. 在演示开启前, 执行命令, 创建 HyperLogLog 插件:

CREATE EXTENSION hll;

如下我们建立表 user_login_log, 存放着用户登录信息. 每次用户登录时, 都会往该表中插入一条记录存放相关登录信息. 这里只创建了演示所必需的若干字段.

CREATE TABLE user_login_log
(
    user_id int, -- 用户 ID, 唯一地标识一名用户.
    login_time timestamp without time zone,  -- 本次登录时间.
    login_ip varchar,  -- 本次登录 IP 信息.
    login_src smallint  -- 本次登录来源: 网页/APP...
)
DISTRIBUTED BY(user_id);

再建立表 user_login_log_hll, 以天为粒度, 存放着该天内 user_id 数据集对应 HyperLogLog 信息.

CREATE TABLE user_login_log_hll
(
    login_date date PRIMARY KEY,
    user_id_hll hll
)
DISTRIBUTED BY(login_date);

之后在每次用户登录时, 通过如下 SQL 来更新 user_login_log 表信息:

-- 字段根据实际情况填充. 
INSERT INTO user_login_log 
VALUES('user_id', 'login_time', ...); 

对 user_login_log_hll 的更新一般有两种模式: T + 1 更新, 实时更新.

  1. 在 T + 1 更新模式中, 一般是在第 T + 1 天的凌晨时间段运行如下 SQL 为第 T 天更新数据信息:
INSERT INTO user_login_log_hll
SELECT CURRENT_DATE - interval '1 day',
       hll_add_agg(hll_hash_integer(user_id), 17, 7)
FROM user_login_log
WHERE login_time >= (CURRENT_DATE - interval '1 day')::TIMESTAMP WITHOUT TIME ZONE
  AND login_time < CURRENT_DATE::TIMESTAMP WITHOUT TIME ZONE;
  1. 在实时更新模式中, 需要根据业务规划预先填充 user_login_log_hll, 如下 SQL:
-- 前后 30 年.
INSERT INTO user_login_log_hll 
SELECT current_date + i, hll_empty(17,7) 
FROM generate_series(-30 * 365, 30 * 365) t(i);

之后再每次用户登录时, 通过 SQL 来更新 user_login_log_hll. 为了降低用户侧感知到的时延, 对 user_login_log_hll 的更新可以以异步的方式进行.

-- 这里 user_id, login_time 取自于用户登录信息. 
UPDATE user_login_log_hll 
SET user_id_hll = hll_add(user_id_hll, hll_hash_integer(user_id)) 
WHERE login_date = login_time::date;

最后通过如下 SQL 可以在千分级误差内快速地估算出某天/某月的日活/月活用户数:

-- 最近一周日活估计量:
SELECT login_date, hll_cardinality(user_id_hll) as uv 
FROM user_login_log_hll 
ORDER BY login_date DESC 
LIMIT 7;

image

与利用 COUNT(DISTINCT user_id) 方式得到的精确日活对比:

image

-- 最近三月月活估计量:
SELECT 
    extract(year from login_date) AS year, 
    extract(month from login_date) AS month, 
    hll_cardinality(hll_union_agg(user_id_hll)) AS uv 
FROM user_login_log_hll 
GROUP BY year, month 
ORDER BY year, month DESC 
LIMIT 3;

image

与利用 COUNT(DISTINCT user_id) 方式得到的精确月活对比:

image

在 ADB PG中使用HLL 的详细说明,可以参见 https://help.aliyun.com/document_detail/64023.html

相关实践学习
AnalyticDB MySQL海量数据秒级分析体验
快速上手AnalyticDB MySQL,玩转SQL开发等功能!本教程介绍如何在AnalyticDB MySQL中,一键加载内置数据集,并基于自动生成的查询脚本,运行复杂查询语句,秒级生成查询结果。
阿里云云原生数据仓库AnalyticDB MySQL版 使用教程
云原生数据仓库AnalyticDB MySQL版是一种支持高并发低延时查询的新一代云原生数据仓库,高度兼容MySQL协议以及SQL:92、SQL:99、SQL:2003标准,可以对海量数据进行即时的多维分析透视和业务探索,快速构建企业云上数据仓库。 了解产品 https://www.aliyun.com/product/ApsaraDB/ads
目录
相关文章
|
9月前
|
SQL 运维 关系型数据库
基于AnalyticDB PostgreSQL的实时物化视图研发实践
AnalyticDB PostgreSQL企业数据智能平台是构建数据智能的全流程平台,提供可视化实时任务开发 + 实时数据洞察,让您轻松平移离线任务,使用SQL和简单配置即可完成整个实时数仓的搭建。
680 1
|
9月前
|
Cloud Native 关系型数据库 OLAP
云原生数据仓库产品使用合集之阿里云云原生数据仓库AnalyticDB PostgreSQL版的重分布时间主要取决的是什么
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
|
9月前
|
运维 Cloud Native 关系型数据库
云原生数据仓库产品使用合集之原生数据仓库AnalyticDB PostgreSQL版如果是列存表的话, adb支持通过根据某个字段做upsert吗
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
|
6月前
|
SQL 关系型数据库 PostgreSQL
PostgreSQL 如何通过身份证号码进行年龄段的统计?
【8月更文挑战第20天】PostgreSQL 如何通过身份证号码进行年龄段的统计?
630 2
|
8月前
|
运维 Cloud Native 关系型数据库
云原生数据仓库AnalyticDB产品使用合集之PostgreSQL版是否直接支持实时物化视图
阿里云AnalyticDB提供了全面的数据导入、查询分析、数据管理、运维监控等功能,并通过扩展功能支持与AI平台集成、跨地域复制与联邦查询等高级应用场景,为企业构建实时、高效、可扩展的数据仓库解决方案。以下是对AnalyticDB产品使用合集的概述,包括数据导入、查询分析、数据管理、运维监控、扩展功能等方面。
146 3
|
9月前
|
关系型数据库 数据库 对象存储
AnalyticDB PostgreSQL基于DMS数据ETL链路开发
PostgreSQL数据库目前被广泛应用于企业的在线业务,这款数据库以其高度的稳定性和完善的产品能力被业界高度赞誉和广泛接受。 本文介绍了两款PostgreSQL引擎的数据库是如何完成一套标准的数据链路同步,开发并让企业可以同时享受PostgreSQL在OLTP & OLAP的场景下的全面能力。
AnalyticDB PostgreSQL基于DMS数据ETL链路开发
|
9月前
|
存储 关系型数据库 OLAP
基于AnalyticDB PostgreSQL数据共享实现企业级跨多业务的敏捷分析
云数据仓库AnalyticDB PostgreSQL 版发布了最新自研的云原生架构实例,实现了跨实例间的数据共享能力。允许进行跨实例间的实时数据共享且无需进行数据迁移,可支持构建安全、高效、灵活的数据分析场景。本文介绍了依托数据共享实现云数仓跨多业务实例的敏捷数据分析方案。
基于AnalyticDB PostgreSQL数据共享实现企业级跨多业务的敏捷分析
|
9月前
|
Cloud Native 关系型数据库 OLAP
从0~1,基于DMS面向AnalyticDB PostgreSQL的数据ETL链路开发
在传统数仓中,往往采用资源预购的方式,缺少面向业务的资源调整灵活性。 在数据分析这种存在明显业务波峰波谷或分时请求的场景下,实例无法按需使用,造成了大量成本浪费。云原生数仓AnalyticDB PostgreSQL产品自2022年2月正式发布了Serverless版之后,依托于内核强大的资源管理能力...
|
9月前
|
关系型数据库 分布式数据库 PolarDB
PolarDB 开源版通过 postgresql_hll 实现高效率 UV滑动分析、实时推荐已读列表过滤
背景PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力.本文将介绍PolarDB 开源版通过 postgresql_hll 实现高效率 UV...
130 0

相关产品

  • 云数据库 RDS PostgreSQL 版