PV、UV 统计方案
868 字
4 分钟
PV、UV 统计方案
业务背景
近期有个CPS相关的需求,其中有一个功能,是对CPS合作商(partner)的引流效果进行统计分析,需要以合作商的维度,统计PV、UV信息(合作商存在多级,但是不超过3级),数据情况大致如下
- QPS,日间峰值360, 夜间低谷80, 均值250
- PV 500W,带合作商信息的数据,预计在100W左右
- 数据实时性要求 5 分钟,准确性要求相对准确
数据收集链路
C端 → nginx → 后端应用 → kafka → CPS统计服务 → MongoDB
PV 统计实现方案
基于 redis,后台线程异步从 redis 分桶数据中,获取增量数据,刷入到 mysql 中
redis 中的 key 命名规则 appns:pv:导流商id:日期(yyyyMMdd):时间(HH:mm),每个 key 默认过期时间为 30 分钟,其中时间分桶规则为每5分钟一个桶,示例如下
| 时间范围(闭区间) | 分桶 |
|---|---|
| 01:00<00>00> ~ 01:04<59>59> | 0100 |
| 01:05<00>00> ~ 01:09<59>59> | 0105 |
| … | … |
| 23:55<00>00> ~ 23:59<59>59> | 2355 |
- 消费数据时,保存到 mongo 后,计算得到对应的 key 集合中,value 使用 redis 的
INCR自增,并将 key 保存到一个 特殊的app:pv:keys中(zset 结构),score 为 yyyyMMddHHmm - 通过定时调度,每5分钟扫描
app:pv:keys中分数 < 5分钟之前score 的 keys,遍历每个key,将对应的增量数据,刷入到数据库中,并从app:pv:keys删除(同时删除对应的 key) - 增加兜底调度,每天凌晨时刻,基于 MongoDB 中的数据重新统计前一天每个
partner的 PV,更新到数据库中
方案优势
- 避免频繁的更新 mysql(每次pv + 1 都更新完全没必要);
- 通过时间分桶方式,等到每个分桶中的增量完全固定之后,再将桶内的数据加回到数据库,降低代码实现的复杂度(否则需要考虑对桶操作的加锁)
- 每日兜底的重新统计任务,可以保证统计的数据准确性
后续优化方案
- mongo写入改为批量,
INCR前在内存中先小批次聚合一下,减少 io 次数 - 如果 parnter 层级过多,子 partner 比较多时,考虑同时聚合后更新 父级partner 的 PV
UV 统计实现方案
如果用户张三,通过 partnerA 的引流链接进入到应用中,partnerA 的 UV + 1, 相同一天,张三又通过 partnerB 的引流链接进入应用时,partnerB 的 UV + 1
技术方案考虑使用 redis 的 HyperLogLog 实现,实现细节如下
- 消费数据时,保存到 mongo 后,计算对应事件的 key,格式为
appns:uv:导流商id:日期(yyyyMMdd),使用PFADD KEY VALUE命令,将对应的 openid 添加到指定的 HyperLogLog 中, 同时将 key 保存到app:uv:keys:yyyyMMdd集合中(只用redis的list) - 定时调度,每5分钟扫描当日的
app:uv:keys:yyyyMMdd,遍历其中的key,再次将数据刷回 mysql - 增加兜底调度,每天凌晨时刻,基于 MongoDB 中的数据重新统计前一天每个
partner的 UV,更新到数据库中,同时清理昨日的app:uv:keys:yyyyMMdd
方案优势
- 较与 set 或者 bitmap 实现形式,HyperLogLog 更加节省内存,标准的 0.81% 误差业务上能接受
后续优化方案
- 考虑在 应用内存中,积攒一小批后,通过
PFADD key element1 element2 element3 ... elementN去操作 HyperLogLog
📎 参考文章
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
相关文章智能推荐
1
在 PVE 上给软路由虚拟机加一个网络 Watchdog
技术分享在 PVE 宿主机上用 Bash 和 systemd timer 实现一个网络 watchdog:先检测公网连通性,连续失败后重启软路由虚拟机,多次自愈无效再升级为重启 PVE 宿主机。
2
命令行自动登录 JumpServer:SSH、TOTP 与密码提示的自动化
技术分享把 JumpServer 登录流程拆成凭据读取和终端交互两层:zsh 从密码管理器安全读取 TOTP seed 与可选密码,expect 只负责响应 SSH 登录过程中的 password 和 Code 提示。
3
git 个人开发工作流
技术分享介绍个人 Git 分支协作流程:以基线分支(如 feature-a)+ 个人开发分支(feature-a-xxx)进行开发,开发分支定期 rebase 同步上游,最终通过 merge(必要时先 squash 整理提交)合回基线;并提供 grebase/gmergebase 等脚本,支持自动推导基线分支、预览计划、带 autostash 的安全 rebase,以及可选 squash/推送/删除分支的安全 merge-back。
4
使用 docker-atrust 连入深信服
技术分享使用 Docker 容器运行深信服 aTrust 客户端,通过 VNC 完成登录,并结合本机 mihomo 配置实现公司内网的 DNS 解析与按域名、IP 的精确代理分流;宿主机暴露 1080 与 8888 端口供 socks5 和 HTTP 代理使用,从而在不安装原生客户端的情况下实现零信任接入并降低对本机的影响。
5
mihomo 使用
技术分享2025-09-30
随机文章随机推荐













