perf(daily-volume): 每日量抓取拆成「体积每 30 分钟 / 条数每天最多 3 次」
=== 现象 ===
用户问:每日日志量不是有定时任务记录吗?为什么还要每次查询?
盘了一遍发现:定时任务确实有(每 30 分钟),接口也确实只读库(实测 0.1ms),
但每轮抓取都顺手跑一次**整天 index/stats** 拿条数(实测 6ms ~ 20s,随负载波动),
2 天 × 多个数据源 × 每 30 分钟 = 一天几十次重查询,纯浪费单实例 Loki 的算力,
还会和用户页面上的查询抢 CPU。
第二条更糟:仓库里所有快照的 partial 全是 true。
根因:partial 里混了两种语义 ——「今天还没过完」和「起点超出 24h」。
后者让昨天/前天的柱子也画成虚线空心,看起来「每天都在进行中」。
=== 修法 ===
1. 抓取按成本拆成两条路径(体积走 volume_range,条数走 index/stats):
- 体积:今天 + 昨天,每 30 分钟刷,54ms~4s,无感
- 条数:只对**已结束**且 entries==0 的天补,每天最多 3 次、间隔≥1h;
尝试次数**先写库再查**,进程中途被杀也不会退化成每 30 分钟重试
2. partial 只表示「今天还没过完」,昨天起是实心柱
3. 0 与「未留存」分开:起点超出 24h 且查不到数据 → **跳过落库**保持 Missing。
否则「数据被 retention 删掉」会被画成「那天没有日志」,比灰色柱误导得多
4. 每次抓取打日志:`[daily-volume] 2026-10-30 体积 291.37 GB 已落库(volume_range 4.27s,34 个桶)`
—— 以后不用猜「到底抓没抓、走的哪条路径」
=== 实测取证(本集群)===
Loki 直接查(port-forward :13100):
10-30(16.8h) volume_range 291.37GB/34桶 index/stats entries=2.21B
10-29(24h) volume_range 121.99GB/19桶 index/stats entries=927.9M
10-28/10-27 volume_range 0 桶、index/stats 0 —— 已被 retention 删掉
同范围 count_over_time 两次 60s 超时(永远别用在每日量上)
平台库里的快照与上述数字一致(288.32 / 121.75 GB),说明落库值可信;
10-27/10-28 的 34.87/25.65 GB 是当时抓的 —— 这正是「Loki 只留 1~3 天,
历史必须自己落库」的实证。
go vet ./services/ ./models/ 干净;go build 通过;go test ./services/ 通过。
This commit is contained in:
1 parent
e4cefa1fa7
commit
b7de337c9e
2 files changed
+187
-53
No files matched your search
@@ -25,6 +25,15 @@ type DailyVolumeSnapshot struct {
|
||||
Entries int64 `json:"entries"` // 日志条数
|
||||
// Partial 该日期是否为"不完整的一天"(当天抓取时还没过完)。
|
||||
// 前端用它区分"真实低峰"和"只统计到一半"。
|
||||
Partial bool `json:"partial"`
|
||||
CapturedAt time.Time `json:"capturedAt"`
|
||||
//
|
||||
// ⚠️ 只表示"今天还没过完"。早期实现把"起点超出 24 小时"也算成 partial,
|
||||
// 导致昨天、前天的柱子也画成虚线空心,看起来像"每天都在进行中"(已修)。
|
||||
Partial bool `json:"partial"`
|
||||
// EntriesAttempts 条数(index/stats)已尝试次数。
|
||||
// 整天跨度统计很贵(实测 6ms ~ 20s,取决于实例负载),
|
||||
// 所以只对"已经过完的天"补,且最多重试 entriesMaxAttempts 次,
|
||||
// 避免每 30 分钟的定时任务无脑重跑一遍。
|
||||
EntriesAttempts int `json:"entriesAttempts"`
|
||||
LastEntriesAttempt time.Time `json:"lastEntriesAttempt"`
|
||||
CapturedAt time.Time `json:"capturedAt"`
|
||||
}
|
||||
Reference in new issue
Block a user