Task:APP 活跃、运行记录与查询优化
应用活跃、运行统计与归档
“应用活跃”根据应用心跳/上报整理活跃设备和时间;“应用运行”处理设备明确上报的包运行时长与打开次数。两条链的设备键、日期维度和统计类型编码不同,做报表时不能只因都含包名和MAC就直接合并。
应用活跃:原始日志到日/月/年
AppActivityConsumer接收Kafka活跃消息,AppActivityLogService生成雪花ID、补服务端create_time,写MySQL ik_thirdparty。原始表按包名+接收日期划分:app_activity_log_{包名中的点替换为下划线}_{yyyyMMdd}。设备时间time_stamp与服务端建表日期分开保留,避免把迟到报文理解为另一天建表依据。
表内partition_index由MAC与CPU拼接后的哈希取1024模计算,分区名为P{序号},建表代码使用(id,partition_index)复合主键。这是同一日表的分区,不是1024张业务表。tableName为@TableField(exist=false)路由属性,不能列为物理列。
AppActivityJob按分区读取原始日志形成设备活跃BO,insertByBo写入TDengine日、月、年三个库的app_activity_detail超级表。月记录的时间归一到月首、年记录归一到年首;不是简单把日表整行累计后就得到可证明的月/年时长。统计数值准确性及重复写语义本次未通过业务记录核验。
| 存储对象 | 核心字段与设计目的 | 本次结构结果 |
|---|---|---|
| MySQL动态原始表 | mac/cpu标识设备,package_name/version_code标识应用,time_interval_config为上报间隔分钟,另保留设备时间、时区、IP、接收时间 | 实测25张,覆盖5个包名、20260916—20260920;含预建日期不能推断已有业务数据 |
TD app_activity_day.app_activity_detail | ts时间戳+data_key复合键;record_time/package_name为TAG | 实测161个子表 |
TD app_activity_month.app_activity_detail | 同一模型,时间归一到月份;标签日期也是归一后的yyyyMMdd | 实测38个子表 |
TD app_activity_year.app_activity_detail | 同一模型,时间归一到年份 | 实测12个子表 |
MySQL app_activity_count | 旧统计实体与CRUD仍在,后台统计页同时具有TD查询路径 | beginDate/endDate与实表不符,详见差异页 |
TD活跃子表为aad_{规范化包名}_{record_time},设备复合标识data_key=mac+cpu;普通列还含version_code/duration/ip/country。tbname是TD子表路由伪列,不是普通业务字段。代码统计接口type为0日、1月、2年。
应用运行:热数据、排行榜和归档
Task统一设备事件入口将运行列表发Kafka,AppRuntimeConsumer过滤不合时长范围、超出配置写入期限或未启用运行采集的包,写入TD热库nebula_ids.flow_app_runtime。包名登记/开关查 询通过device模块工具完成。运行上报还可能回填flow_task_device首次运行时间,是对投放效果的验证链。
运行子表名为flow_app_runtime_{规范化包名}_{day},day来自归一到日的record_time。data_key是去除冒号的MAC、下划线、CPU ID拼接;这与活跃链的直接拼接不同。record_time与data_key构成实测复合键;package_name/day是TAG,create_time保留接收时间,duration/open_time分别表达运行时长与打开次数。TAG不应按普通MySQL外键解释。
| 对象 | 用途 | 结构与关联 |
|---|---|---|
TD nebula_ids.flow_app_runtime | 近期运行明细、当前消费者写入 | 实测1567子表;实体及Mapper标明tdAppRuntime |
TD app_runtime_archive.flow_app_runtime | 归档运行明细、历史查询 | 实测261子表;同一列与标签模型,部分压缩算法不同 |
MySQL nebula_ids.stats_app_runtime_top | 按包/版本/日期预计算运行排行榜,避免每次扫明细 | 唯一键(date,package_name,type,version_code);type为0月、1年、2日,与活跃编码不同;duration分钟、open_time次数、device_count设备数、record_count记录数 |
MySQL ik_yudao_task.task_app_runtime_archive_record | 记录按天归档任务的执行结果 | day归档日期,state=0/1/2执行中/成功/失败,count迁移量,remark说明;仅主键,未有day唯一约束 |
AppRuntimeArchiveJob根据归档任务参数调用备份/恢复脚本并写归档记录;源码中存在SSH执行和脚本传输能力。