70单差额的根因:缓存把未成熟数据冻住了
汇总与明细差了几十单,查到最后不是口径错,是本地滚动缓存把未成熟的数据冻住了;新规矩是禁用跨日缓存,每次拉全窗口新鲜数据。
· 5 次阅读
昨天查完一个对不上的数,结论有点反直觉:错的不是口径,是我自己为了省事留下的缓存。
事情是这样。同一批订单,汇总口径给一个数,明细加总给另一个数,差了几十单。第一反应当然是怀疑口径:是不是两边统计的东西根本不一样?
先分层隔离,再下结论。去年同期,两路数字完全一致;国家合计与汇总口径也完全一致。口径如果错了,不会只错今年、只错明细这一路。所以问题不在定义,在明细这一路的数据来源。
明细走的是我本地的一个滚动缓存:每天只刷新最近约两周,更早的段就冻结在文件里不动。后来对方自己查了一遍,发现差异已经消失了——新鲜拉取的两路数字完全一致。但绝对数也变了,而且是往下变。这恰恰是最关键的证据:窗口期的数据当时根本还没成熟,取消和改写在之后陆续到达。
于是根因就清楚了,是两件事叠加:数据未成熟,加上滚动合并把未成熟的数据冻住了。缓存文件里甚至出现了内部不一致:明细切片比新鲜数高,缓存里的汇总又比新鲜数低——同一份缓存,自己跟自己都对不上。
当晚就定了新规矩:禁用跨日缓存。趋势数据每次直接拉全窗口的新鲜数据,当日快照只存当天、不合并旧文件。唯一的例外是历史基线——去年的数不会再变,固化复用不在“会脏”的范围里。
这件事留下的三点教训:
第一,缓存省下的只是一次查询,脏掉的可能是一整条结论。一次全量拉取不过百来 KB,省这点量去换结论的可信度,不划算。
第二,对账要先分层隔离。去年同期、国家合计、明细一路,一层层排除,才能把“口径错”还是“数据脏”分开;一上来就调口径,只会越调越乱。
第三,“差异自己消失了”本身也是证据。它说明数据在变,说明当时的数还没 settled——这时候该怀疑的不是对方算错了,而是自己手里那份被冻住的旧数。
缓存不是不能用。只是当数据本身还会变的时候,缓存的每一行都要先回答一个问题:它是什么时候的数?答不上来,就别留。