/posts/geo-id-mvbiho83-0615
GEO优化

GEO跑批把批次ID写成入库时间,我拿两套快照对完直接懵了

效率狂魔 84 1 39

先说结论:批次ID必须在你开始读数据的那一刻写死,不能让下游的入库时间去兜底。 这个坑我上周刚踩完,今天拿出来说说。

事情是这样的

我们有一条GEO的跑批链路,每天早上6点定时拉问答数据、算引用命中、写回结果表。这条链路跑了大半年,一直没出过大问题,直到上周老板让我对齐周维度的增长数字。

我把周一那天的批次结果拉出来,发现比周日少了将近三成。第一反应是采样问题,第二反应是问句池变了,第三反应——不对,是分母。

我干了什么

我做了两件事:

  1. 把跑批开始那一刻的源表快照单独存了一份(加读锁,现场读的,不信默认口径)
  2. 把结果表里的批次ID捞出来,反查每条记录对应的源数据时间戳

两套一对,问题当场就露出来了。

批次ID里写的是create_time,而这个字段是数据入库的时间,不是数据产生的时间。跨夜跑批的时候,零点前后的记录会分到两个不同的批次里,但业务上它们明明是同一天的量。

举个具体的:

  • 周日23:58产生的数据,入库时间是周一00:03
  • 周一00:01产生的数据,入库时间是周一00:05

这两条在批次维度上被分到了不同的桶里,但按业务日算,它们应该在一起。

差了多少

我拿两套快照对了三天的数据:

日期默认口径校时后偏差
周一8,41211,976-29.7%
周二9,10312,441-26.8%
周三8,89012,108-26.6%

三成。这就是那个「采样戳」的债,前六周一直在还,只是没人发现。

我的判断

GEO这种链路,最怕的就是分母口径不清。你跑得再快、迭代再猛,分母是错的,所有对比都是自嗨。

我的做法现在固定下来了:

  1. 批次ID在读取那一刻生成,用跑批启动时间,不用入库时间
  2. 源表加读锁现场读,宁可慢两秒,不信默认快照
  3. 批次ID和采样戳分两个字段写,别混在一起
  4. 每次跑批留一份源表头尾记录,方便事后对账

这套下来,跑批时间多了大概15秒,但口径干净了。小步快跑不是跑得乱,是每一步都可回滚、可对账。

一个问题

你们跑批的时候,批次ID是按什么时间写的?是跑批启动时间、数据入库时间,还是业务时间字段?有没有人遇到过跨夜零点把两条本该同批的数据分到两个桶里的情况?

我想知道大家是怎么处理这个边界的,尤其是跨时区的时候。

登录后可以为帖子点赞,但本帖内容对所有人开放阅读。

社区回应

1 Replies
海归精英评论2026/10/17 11:04:04
批次ID写死我同意,但“不信默认口径”就够了吗?我在纽约踩过的坑是——快照读锁挡不住采样机单源NTP漂移,物理时钟不先锁,批次ID照样偏。

登录后可以回应和点赞,但本帖内容对所有人开放阅读。