perf(ops-report): eliminate logs full-table scans from the report path - #793
Open
mguozhen wants to merge 2 commits into
Open
perf(ops-report): eliminate logs full-table scans from the report path#793mguozhen wants to merge 2 commits into
mguozhen wants to merge 2 commits into
Conversation
The ops daily report rebuilt on every 10-minute cache expiry by scanning the whole logs history (~45M rows, measured 100s+ on prod) plus unbounded scans of tokens/top_ups/subscription_orders. This change removes the logs scans from the request path: - GetOpsKeyDailyUsage (plg DAU) now aggregates quota_data hourly rollups (~500 rows/day) instead of raw logs; same trade-off GetOpsAllKeyDailyUsage already documents (counts playground too). Users are still filtered to the plg cohort in memory. - New ops_user_log_stats pre-aggregated table replaces the per-user playground/API-key scan of the full logs history. A background task (master node, 5-min interval) incrementally folds new consume logs in, backfilling on first run; GetOpsUserLogStats reads the table and falls back to the direct scan only until the first backfill completes. - GetOpsUsersLastIP is bounded by the report window so the MAX(id) pass never walks the oldest logs. No relay/router paths touched; console-only admin report change. Tests: model suite green (3 new tests for the aggregation); controller ops tests green. Pre-existing controller failures (seedance asset worker, channel validation) reproduce on origin/main.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem / Background
/ops-report(运营日报) 在每次 10 分钟缓存过期后重建报告时,会对 logs 表(约 45M 行)做全表/全历史扫描,页面加载因此达到数十秒到 100s+;数据持续增长下风险会进一步放大。Evidence / Reproduction
model/ops_report.go:GetOpsKeyDailyUsage(plg DAU 数据源)的注释自证: "the optimizer full-scans ~45M rows there (measured 100s+ on prod)" —— 30 天窗口几乎覆盖整张 logs 表。model/ops_report.go:GetOpsUserLogStats无时间窗口,每次重建都扫描整个 logs 历史: "scans the whole logs history for the plg cohort no matter which day range is selected"。GetOpsUsersLastIP(stripe 报告)同样MAX(id)全历史扫描 logs。/api/data/ops_report与/api/data/ops_report_stripe的请求路径上,且重建发生在opsReportMutex全局锁内(锁内还可能在opsSyncAdsSpend中发起 Google Ads 网络调用),期间所有 ops 报告请求排队。Root Cause / Hypothesis
报告需要的是"全历史 per-user 统计 + 窗口内 per-user-per-day 统计",但实现方式是每次重建时直接从大表实时聚合。logs 是只增的大表,任何"全历史/宽窗口 + GROUP BY"查询的成本都随数据量线性增长;缓存只推迟了问题,没有消除扫描本身。
Scope / Design
只改动 console 管理端报告路径,不触碰 relay/计费/鉴权。
quota_data(GetOpsKeyDailyUsage):复用dau_scope=all已验证的路径(小时级 rollup,~500 行/天,user_id有索引),plg 用户过滤在内存完成。Trade-off 与GetOpsAllKeyDailyUsage一致:quota_data 包含 playground 消耗(不再仅 token_id>0 的 API-key 调用),已在注释中说明。ops_user_log_stats预聚合表(model/ops_user_log_stats.go):per-user 全历史统计(首次 playground/api-key 时间、计数、最后请求时间),由 master 节点后台任务(5 分钟间隔)增量折叠新 consume 日志,首次运行自动全量回填;游标存ops_user_log_stats_meta,崩溃可恢复。GetOpsUserLogStats改读该表,回填完成前自动 fallback 到原查询,部署过渡期报告不为空。GetOpsUsersLastIP加报告窗口时间下限,MAX(id)不再扫最老日志。LOG_DB.AutoMigrate;main.go启动StartOpsUserLogStatsSyncTask()(仅 master 节点,Rule 11 单写者,upsert 幂等)。Impact / Risks
dau_scope=all口径对齐(注释已注明)。Validation / Acceptance
go build ./...通过。go test ./model/...全绿,新增 3 个测试覆盖:playground/API-key 判定与first_*语义、增量累加不覆盖历史、回填前 fallback。TestModelAPISeedanceAssetTaskWorker*/TestValidateChannelRejectsModelAPISeedanceProxy)在干净的origin/mainworktree 上同样复现,与本次改动无关。newapi-console(migrateLOGDB 自动建新表)。部署后观察首轮回填完成后接口响应时间。