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

简介: 在互联网产品的日常运营中, 经常需要统计产品的日活/月活用户量. 本文介绍了在[分析型数据库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版是一种支持高并发低延时查询的新一代云原生数据仓库,高度兼容MySQL协议以及SQL:92、SQL:99、SQL:2003标准,可以对海量数据进行即时的多维分析透视和业务探索,快速构建企业云上数据仓库。 了解产品 https://www.aliyun.com/product/ApsaraDB/ads
目录
相关文章
|
关系型数据库 分布式数据库 PolarDB
PolarDB 开源版通过 postgresql_hll 实现高效率 UV滑动分析、实时推荐已读列表过滤
背景PolarDB 的云原生存算分离架构, 具备低廉的数据存储、高效扩展弹性、高速多机并行计算能力、高速数据搜索和处理; PolarDB与计算算法结合, 将实现双剑合璧, 推动业务数据的价值产出, 将数据变成生产力.本文将介绍PolarDB 开源版通过 postgresql_hll 实现高效率 UV...
507 0
|
关系型数据库 分布式数据库 数据库
沉浸式学习PostgreSQL|PolarDB 1: 短视频推荐去重、UV统计分析场景
本实验场景:短视频推荐去重、UV统计分析场景. 欢迎一起来建设数据库沉浸式学习教学素材库, 帮助开发者用好数据库, 提升开发者竞争力, 为企业降本提效. 本文的实验可以使用永久免费的云起实验室来完成. https://developer.aliyun.com/adc/scenario/exp/f55dbfac77c0467a9d3cd95ff6697a31 如果你本地有docker环境也可以把镜像拉到本地来做实验.
702 0
|
SQL 缓存 监控
PostgreSQL 监控1统计进程和统计信息的解读|学习笔记(二)
快速学习PostgreSQL 监控1统计进程和统计信息的解读
653 0
PostgreSQL 监控1统计进程和统计信息的解读|学习笔记(二)
|
SQL 监控 IDE
PostgreSQL监控1统计进程和统计信息的解读|学习笔记(一)
快速学习PostgreSQL监控1统计进程和统计信息的解读
898 0
PostgreSQL监控1统计进程和统计信息的解读|学习笔记(一)
|
SQL 监控 Oracle
PostgreSQL pgcenter - 采样、统计、性能诊断、profile、cli小工具
标签 PostgreSQL , pgcenter , pg_top , awr , perf insight , 等待事件 , perf , profile , 采样 , 统计信息 背景 PostgreSQL 性能诊断的方法很多: 例如: 1、函数的性能诊断,PROFILE。 《PostgreSQL 函数调试、诊断、优化 & auto_explain & plpro
2317 0
|
SQL 弹性计算 关系型数据库
HTAP数据库 PostgreSQL 场景与性能测试之 3.1 - (OLAP) 大表JOIN统计查询-10亿 join 1亿 agg
标签 PostgreSQL , HTAP , OLTP , OLAP , 场景与性能测试 背景 PostgreSQL是一个历史悠久的数据库,历史可以追溯到1973年,最早由2014计算机图灵奖得主,关系数据库的鼻祖Michael_Stonebraker 操刀设计,PostgreSQL具备与Oracle类似的功能、性能、架构以及稳定性。 PostgreSQL社区的贡献者众多
2328 0
|
SQL 关系型数据库 数据库
PostgreSQL:SQL信息统计拓展
概述 pg_stat_statements是PostgreSQL数据库的一个拓展插件,用于收集数据库中的SQL运行信息,例如SQL的总执行时间,调用次数,共享内存命中率等信息。用于监控数据库的性能,是数据库性能监控的重要拓展模块pg_stat_statements 默认在PG的源码包中就有,无需下...
2311 0
|
SQL 关系型数据库 数据库
PostgreSQL技术周刊第23期:PostgreSQL统计信息
PostgreSQL(简称PG)的开发者们:云栖社区已有5000位PG开发者,发布了3000+PG文章(文章列表),沉淀了700+的PG精品问答(问答列表)。 PostgreSQL技术周刊会为大家介绍最新的PG技术与动态、预告活动、最热问答、直播教程等,欢迎大家订阅PostgreSQL技术周刊。
4652 0
|
SQL 关系型数据库 数据库
PostgreSQL统计信息
PostgreSQL统计信息 1.数据库统计信息概览 2.pg_stat_database关键指标 postgres=# select * from pg_stat_database where datname='postgres'; -[ RECORD 1 ]-----+-----------...
4560 0
|
关系型数据库 数据库 PostgreSQL
【PostgreSQL系列直播】PostgreSQL数据库统计信息讲解
主讲人 王健(绛云)阿里云数据库专家服务组PostgreSQL dba,对于PostgreSQL性能优化,问题排查诊断有一定经验,内核源码也有一定了解。 直播内容 内容介绍:帮助明白这些指标的含义,学会如果根据这些指标分析问题和发现问题。
2678 0

相关产品

  • 云数据库 RDS PostgreSQL 版
  • 推荐镜像

    更多