yumi-java/rc-service/rc-service-console/docs/country-dashboard-data-query.md

175 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 国家数据大屏数据查询技术文档
## 目标
国家数据大屏接口 `/console/datav/country-dashboard` 原来在页面请求时实时扫描订单、用户、游戏流水和 wallet 分表。线上慢查询主要集中在 `wallet_gold_asset_record_1..12` 的游戏流水、游戏人数统计。当前改为 SQL 指标预聚合,页面优先查询汇总表;汇总缺失或请求范围不符合预聚合口径时,才回退原实时 SQL。
## 查询入口
- Controller: `DatavRestController#countryDashboard`
- Service: `CountryDashboardServiceImpl#query`
- DAO: `CountryDashboardDAO`
- Mapper: `CountryDashboardDAO.xml`
查询参数:
- `periodType`: `DAY` / `WEEK` / `MONTH` / `ALL`
- `startDate`, `endDate`: 闭区间日期,后端转为 `[startDate 00:00:00, endDate + 1 day 00:00:00)`
- `countryKeyword`: 国家码或国家名模糊匹配
- `sysOrigin`: 系统来源,预聚合查询必须传
## 预聚合表
### `country_dashboard_daily_metric`
日级 SQL 指标表,按 `stat_date + sys_origin + country_code` 唯一。
用途:
- 保留日级汇总结果。
- 作为 `ALL` 周期金额汇总的数据来源。
- 作为历史回填和排查的基础日表。
### `country_dashboard_period_metric`
周期汇总表,按 `period_type + period_key + sys_origin + country_code` 唯一。
周期键示例:
- `DAY`: `2026-05-07`
- `WEEK`: `2026-W19`
- `MONTH`: `2026-05`
- `ALL`: `ALL`
页面查询优先读取这张表。
### `country_dashboard_period_user_metric`
周期用户去重明细表,按 `period_type + period_key + sys_origin + country_code + user_id + metric_type` 唯一。
当前维护的 `metric_type`
- `COUNTRY_NEW_USER`: 新增用户人数
- `LUCKY_GIFT_USER`: 幸运礼物用户人数
- `GAME_USER`: 游戏用户人数
`WEEK/MONTH/ALL` 的人数类指标不再从日表简单相加,而是基于这张明细表聚合,避免同一个用户跨多天被重复计算。
## 查询路由
`CountryDashboardServiceImpl#shouldUsePrecomputedMetrics` 会先判断是否能走预聚合。
走预聚合的条件:
- `sysOrigin` 不为空。
- `DAY`: 查询范围内每一天都有 `country_dashboard_period_metric` 数据。
- `WEEK/MONTH`: 查询范围必须按周期边界对齐,当前未结束的周/月允许到今天。
- `ALL`: 无 `startDate/endDate` 时固定走 `period_type=ALL, period_key=ALL`。如果汇总表未回填,返回空汇总,不再回退全历史实时扫描。
`DAY/WEEK/MONTH` 不满足条件时回退原实时 SQL保证数据不因预聚合缺失而返回错误。`ALL` 不回退实时 SQL是为了避免一次后台点击触发全历史 wallet 分表扫描。
## 刷新任务
任务类:`CountryDashboardDailyMetricTask`
默认任务:
- 每 10 分钟刷新最近 1 天:`red-circle.country-dashboard.refresh-today-cron`
- 每天 00:20 刷新最近 8 天:`red-circle.country-dashboard.refresh-recent-cron`
默认平台:
```yaml
red-circle:
country-dashboard:
refresh-sys-origins: LIKEI
```
需要刷新多个平台时配置为逗号分隔,例如:
```yaml
red-circle:
country-dashboard:
refresh-sys-origins: LIKEI,TARAB
```
刷新链路:
1. 刷新日表 `country_dashboard_daily_metric`
2. 刷新对应 `DAY` 周期表和用户去重明细。
3. 根据最近日期刷新受影响的 `WEEK``MONTH`
4. 基于已存在的日表和日级用户明细刷新 `ALL`
## 指标来源
SQL 预聚合指标:
- 新增用户:`user_base_info`
- 新用户充值、官方充值、Google 充值:`order_purchase_history`
- MifaPay 充值:`order_user_purchase_pay`
- 代理充值:`likei_wallet.user_freight_balance_running_water`
- 工资兑换:`user_salary_account_running_water`, `user_salary_diamond_running_water`
- 幸运礼物流水/返奖:`game_lucky_gift_count`
- 游戏流水/返奖:`wallet_gold_asset_record_1..12`, `game_lucky_box_count`
- 游戏人数:`country_dashboard_period_user_metric``GAME_USER`
仍实时从 Mongo 聚合的指标:
- 礼物消耗:`gift_give_running_water`
- 幸运礼物主播分成:`gift_give_running_water`
- 日活:`user_daily_active_log`
- 留存:`user_daily_active_log` + 注册 cohort
## 上线和回填
上线前可以先执行:
- `sql/20260507_country_dashboard_daily_metric.sql`
- `sql/20260507_country_dashboard_period_metric.sql`
为避免遗漏console 的刷新和手动回填入口会先执行同等的 `CREATE TABLE IF NOT EXISTS` 检查,再写入预聚合数据。
首次上线后,预聚合表为空时接口会回退实时 SQL。为了尽快切到预聚合需要先回填最近常用查询范围例如最近 8 天、当前周、当前月。
`ALL` 的数据由已回填的日表和日级用户明细汇总而来。如果需要后台“全部”展示完整历史,必须先完成历史日数据回填;否则 `ALL` 只代表当前已经进入预聚合表的数据范围。
手动回填入口:
```bash
curl -X POST 'http://127.0.0.1:{console_port}/console/datav/country-dashboard/backfill?startDate=2026-04-08&endDate=2026-05-07&sysOrigin=LIKEI'
```
该入口会按天重算日表和 `DAY` 周期,再刷新受影响的 `WEEK``MONTH``ALL`
## 验证 SQL
检查某天是否已刷新:
```sql
SELECT stat_date, sys_origin, COUNT(1)
FROM country_dashboard_daily_metric
WHERE sys_origin = 'LIKEI'
GROUP BY stat_date, sys_origin
ORDER BY stat_date DESC;
```
检查周期汇总:
```sql
SELECT period_type, period_key, sys_origin, COUNT(1)
FROM country_dashboard_period_metric
WHERE sys_origin = 'LIKEI'
GROUP BY period_type, period_key, sys_origin
ORDER BY period_type, period_key DESC;
```
检查用户去重明细:
```sql
SELECT period_type, period_key, metric_type, COUNT(1)
FROM country_dashboard_period_user_metric
WHERE sys_origin = 'LIKEI'
GROUP BY period_type, period_key, metric_type
ORDER BY period_type, period_key DESC, metric_type;
```