先把“修复前”和“修复后”当成两段独立观测期,各自保留原始回传日志、事件标识和口径说明,再决定是保留旧数据、改写归因,还是退出该转化目标。直接覆盖或删除修复前的记录,通常会让后续判断失去对照,也无法解释为什么报表在修复当天出现跳变。
重复触发至少有三种可区分的来源,处理方式并不相同。第一种是页面本身重复上报,例如表单提交按钮被连续点击,或提交成功后页面未跳转,用户再次点击。第二种是回传链路重复,例如同一事件在客户端和服务端各上报一次,或重试机制把同一请求发了多次。第三种是归因口径重复,例如同一用户在短时间内完成注册与下单,两个动作被计入同一个转化目标。
区分方法不是看转化总数涨了多少,而是看单条记录的字段。假设一次投放中,同一event_id在日志里出现两条,时间戳相差不到一秒,且用户标识一致,更接近上报重复;如果event_id不同但订单号相同,更接近业务动作被拆成多次触发。前者要修上报逻辑,后者要修事件定义。动作不同,保留记录的方式也不同。
更稳妥的做法是保留原始回传日志不动,在旁路增加一列或一张表,标注该条记录是否属于重复、依据是什么、由谁在什么时间判定。这样做的结果是:修复前的报表仍然可复现,修复后的口径也能单独统计,两者可以对照。
具体动作可以这样落地:把原始事件按event_id、用户标识、事件时间、转化目标名称导出;对疑似重复的记录打上duplicate_of字段,指向被判定为首次的那条记录;修复上线时记录一个明确的时间点或版本号。之后看数据时,用这个时间点切分,而不是把新旧数据混在一起算总量。
这种保留方式的适用前提是:重复量占比较小,且团队需要向投放或客户解释修复前后的差异。如果重复量极大、已经严重影响出价模型,保留全部原始记录的同时,还需要给优化系统提供一份去重后的回传,否则模型会继续按虚高转化学习。
当重复来自归因口径而非技术故障时,改写归因是合理选择。例如同一笔订单同时触发“提交订单”和“支付成功”两个转化目标,如果两个目标都被当作同等价值的转化,就会重复计入。此时可以把其中一个改为辅助事件,或调整转化目标的价值权重,让主目标只保留一次。
但改写归因不能用来掩盖上报故障。如果一条记录在日志里出现两次,说明链路本身有问题,只改归因口径会让报表看起来正常,实际回传仍在重复。判断依据是:改写后,原始日志里的重复条数是否下降。如果没有下降,说明改的只是展示层,问题还在源头。
改写归因时同样要保留修改记录:改的是哪个转化目标、从什么时间开始生效、旧口径下同期数据是多少。缺少这三点,后续对比会失去基准。
退出是一种取舍,不是默认动作。适用前提通常是:该转化目标重复率长期偏高,修复成本大于它带来的优化价值,且存在另一个更干净的目标可以替代。例如表单重复提交严重,但电话拨号事件回传稳定,可以考虑暂时以电话事件作为主要优化目标。
退出的动作要记录清楚:停用哪个目标、从什么时间停用、替代目标是什么、停用期间的历史数据如何归档。结果是,后续回看时会知道某段时间的数据缺口是主动选择,而不是丢失。如果只是把目标关掉却不留说明,下一轮排查会误以为回传中断。
退出并不等于删除。已经积累的修复前记录仍有对照价值,尤其是用来估算重复率对成本指标的影响时。删除之后,你只能看到修复后的结果,无法回答“修复到底改变了多少”。
修复上线后,不要立刻用总量下降来证明处理正确。总量下降还可能来自投放缩减、流量结构变化或统计延迟。更可靠的做法是设一段对照期:修复前后各取相同长度的窗口,比较重复记录条数、去重后转化数、以及单条记录的字段分布。
假设修复前一周日志中有若干条记录共享同一用户标识和相近时间戳,修复后同一类记录消失,同时去重后转化数没有明显变化,这更支持“重复被消除”的解释。如果去重后转化数也大幅下降,需要先排查是否误删了正常记录,而不是直接认定修复成功。
把这段对照结论和修复标记一起归档,下一次出现类似跳变时,就能快速判断是新问题还是旧修复的延续。