大年初一,我在春晚的背景音里清理数据库

大年初一,我在春晚的背景音里清理数据库。电视里在唱难忘今宵,我盯着屏幕上的 SQL 窗口,一行行 UPDATE 和 DELETE,把近三个月爬虫抓来的几百万条商品数据里混进去的垃圾一点点挑出来。背景音越喜庆,我后脖颈越凉。这他妈是第三次了。

问题出在异步采集的异常处理上。为了抢在竞争对手前面,我把爬虫改成了多线程+异步IO,每个线程独立抓取、解析、入库。速度是上去了,但有个致命的假设:目标网站的 DOM 结构是稳定的。结果人家年底改版,商品详情页的 class 名悄悄换了,从“product-price”变成了“price-main”。一半的线程解析失败,抛了异常,但另一半线程还在疯狂工作。异常处理那块我图省事,只打了 log,没中断进程,更没回滚已经插入的脏数据。于是,正常的SKU价格和一堆“None”、“0”、“-1”以及上一页的标题碎片,全部搅在一起,进了同一张表。最骚的是,因为入库时用了 INSERT IGNORE(为了避免重复),这些乱七八糟的数据因为主键不同,全都成功写进去了。等三天后数据分析师跑报表发现价格分布出现诡异峰值时,已经晚了。

清理的逻辑不复杂,但极其磨人。首先得把“正常数据”的特征找出来:价格字段是数值型且在合理区间(比如10-10000),标题字段长度大于5且不含乱码字符。但麻烦在于,那些脏数据里也偶尔混着符合这些特征的记录,比如碰巧抓到了别的页面的正常价格。所以不能简单 DELETE WHERE price=0。我得写一个评分脚本,给每条记录打分:价格是否在历史同类目区间内?标题关键词是否匹配类目?图片URL是否存在?最后还得人工抽样校验。春晚播到小品的时候,我写完了第一个版本的清洗脚本,跑起来,误杀率大概15%。又得调。

这次给我的教训不是技术上的,是心态上的。那种对“快”的病态追求,在2018年做SEO批量建站时就有苗头,总觉得抢时间就是一切。到了2020年带团队,为了赶甲方交付周期,这种心态更被放大了。结果呢?快出来的东西都是豆腐渣,最后返工的时间远超省下的时间。这次数据事故,前后清理+重抓+校验,耗掉我整个春节假期,原本计划上线的新推荐算法模型因为数据源脏了直接延期。所谓的“效率”成了最大的低效。

所以现在我的爬虫,核心逻辑里嵌了一个“巡检机器人”。每批次数据入库前,不是直接进主表,而是先到一个 staging 表。一个独立的进程会基于历史统计指标(字段非空率、数值分布、枚举值集合等)自动跑一遍检查,任何字段的异常率超过阈值(比如5%),整个批次的入库流程自动挂起,并触发告警到手机。同时,主采集进程会捕获特定异常(如DOM解析大面积失败),自动降级到“保守模式”——改用更稳定的XPath路径,甚至直接暂停,等人工介入。这个机制让整体采集速度慢了大概20%,但再也没出过需要手动清理几天的事故。

慢就是快,稳就是赢。这话听起来像机场成功学,但真是用真金白银和头发换来的。当电视里开始倒计时拜年,我总算把最后一批清洗干净的数据导回生产库。看着监控面板上各项指标恢复正常,那种疲惫的踏实感,比任何新年祝福都实在。搞技术,尤其是和数据打交道,敬畏心比炫技重要一万倍。你写的每一行“容错”代码,都是在给未来的自己省时间,或者说,赎罪。

© 版权声明
THE END
喜欢就支持一下吧
点赞56 分享