有条件的结论是:只要把“已确认结果”和“待补结果”在落盘时就分开存放,限流最多只会拖慢补数进度,不会污染已经拿到的数据。反过来,如果脚本把所有返回值先堆在内存里、等整批跑完再统一写入,那么一次限流就可能让前面几百次成功调用全部作废——这是让上述结论失效的典型反例。
限流发生时,真正需要保护的不是“跑完了多少条”,而是“哪些条目的结果已经可以被核对”。对关键词指数查询来说,一次成功返回通常包含三样东西:查询词、返回的指数值或区间、以及调用发生的时间点。这三样齐全,才算一条可用记录。
把记录分成两类落盘:
这样做的直接好处是,限流后你不需要重新判断“刚才跑到哪了”,只要读待补清单继续即可。动作上,建议每成功一条就追加写入一次,而不是攒够一批再写。代价是写入次数变多,但对查询类脚本来说这点开销远小于重跑成本。
遇到限流,第一反应不该是立刻换 IP、换账号或加大重试次数。这些动作会让“到底是限流还是别的问题”变得更难判断。更稳的顺序是:
探测请求返回正常,说明冷却有效,可以继续按待补清单补数;仍然被拒,说明限制条件可能不只是频率,还可能和并发数、单次批量大小或调用时段有关。此时调整并发或批量,比盲目等待更能解决问题。
假设脚本要查 500 个词,每 100 个词写一次文件。跑到第 320 个时触发限流:
两种方式的差别不在限流本身,而在“丢失窗口”有多大。逐条落盘把窗口压到最小,代价是磁盘写入更频繁。如果查询量很大,可以折中为每 10 到 20 条落盘一次,但要接受对应条数的重跑。
限流之后,常见分歧是:运营认为“数据已经拿到了”,技术认为“还差一批没补”。分歧的根源往往不是谁对谁错,而是双方看的是不同文件。
把分歧转成可核对的项目,做法是让每个角色都能看到同一份状态:
当这些信息放在同一份记录里,讨论就从“跑完没有”变成“还差哪几条、为什么差”。下一步动作也随之明确:要么继续补数,要么先接受当前覆盖率做初步判断,并标注哪些结论还缺数据支撑。
如果查询本身要求所有条目在同一时间窗口内取回,比如做跨词的同刻对比,那么逐条落盘反而会引入时间偏差,此时应优先保证同一批次的原子性,并接受限流后整批重跑。是否采用逐条保护,取决于你对“时间一致性”和“重跑成本”哪个更敏感。
先确认你的查询是否对时间窗口敏感;如果不敏感,就按逐条落盘加待补清单执行,并在下次限流前把冷却和并发参数固定下来,这样每一步的结果都能直接决定下一步是补数还是收尾。