需求背景:
平台需要接入游戏数据, 出回收报表和留存报表, 记录一下留存报表开发过程~
00.效果展示
留存概念:
第X日留存 = (当天新增的用户中,新增日之后的第X天还登录的用户数)/第一天新增总用户数。
比如:一条2023-03-01的数据, 它的第30日留存就是: 在1号访问的用户中(假设有300个), 在2023-03-31仍然访问该网站(假设有30个)的用户所占比例(30/300=10%)。
01.数据来源
思路:客户端上报游戏使用者相关信息, 服务端接到参数后存入redis。
代码:
// 日期:流量编码:产品:机型
String today_key = "xxx:" + date;
String today_value = String.format("%s:%s:%s:%s", date, source, productName, brand);
String rds_key = "xxx:" + today_value;
String rds_key_uv = rds_key + ":uv";
String rds_key_pv = rds_key + ":pv";
String rds_key_user = rds_key + ":user";
knife4jRedis4Manager.redisTemplate(7).executePipelined(new SessionCallback<Object>() {
@Override
public Object execute(RedisOperations operations) throws DataAccessException {
operations.opsForSet().add(today_key, today_value);
// 用HyperLogLog来估算每天的UV PV
operations.opsForHyperLogLog().add(rds_key_uv, oaid);
operations.opsForHyperLogLog().add(rds_key_pv, device.getMessageKey());
// 这里用来存放每个维度下访问的用户oaid 留存分析核心数据
operations.opsForSet().add(rds_key_user, oaid);
operations.expire(today_key, 3, TimeUnit.DAYS);
operations.expire(rds_key_uv, 3, TimeUnit.DAYS);
operations.expire(rds_key_pv, 3, TimeUnit.DAYS);
// 要分析30天的留存 设置35的过期
operations.expire(rds_key_user, 30, TimeUnit.DAYS);
return null;
}
});
02.定时任务持久化数据
建表:
CREATE TABLE `xxx` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增主键',
`date` varchar(10) COLLATE utf8mb4_bin NOT NULL COMMENT '日期',
`sourceId` varchar(128) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '流量编码',
`product` varchar(32) COLLATE utf8mb4_bin NOT NULL COMMENT '产品',
`brand` varchar(16) COLLATE utf8mb4_bin NOT NULL DEFAULT '' COMMENT '机型',
`userPV` int(11) NOT NULL DEFAULT '0' COMMENT '用户PV',
`userUV` int(11) NOT NULL DEFAULT '0' COMMENT '用户UV',
`d1UV` int(11) NOT NULL DEFAULT '0', --存放D1重复访问的用户UV数量, 以下类似
`d2UV` int(11) NOT NULL DEFAULT '0',
`d3UV` int(11) NOT NULL DEFAULT '0',
`d7UV` int(11) NOT NULL DEFAULT '0',
`d15UV` int(11) NOT NULL DEFAULT '0',
`d30UV` int(11) NOT NULL DEFAULT '0',
`createTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录创建时间',
`updateTime` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '记录更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `unique_key` (`date`,`sourceId`,`product`,`brand`) USING BTREE
) ENGINE=InnoDB COMMENT='留存报表';
任务:
我这里开了两个任务来跑数据,
第一个任务是纯跑前一天的新增数据, 3-24跑3-23拿到这一天的PV UV
第二个任务是从redis里拿对应维度各天的用户UV 计算留存