宣传里都说快。真去做一套 号码快速去重软件,会发现:把 80 万行丢进去,卡住的往往不是“比不比得过”,而是文件还没解开、规范化还在逐行正则、数据库还在一条条 insert。最后那步对规范化键做存在判断,数据结构和哈希表早就很成熟。
所以第一版不要先上布隆过滤器、不要先上分布式。先把时间花在哪一段测清楚。百万级表格为什么先坏,见 百万号码批量去重;更大规模的存储布局见 亿级秒级去重。
先按四个阶段计时,再谈优化
给任务打点,至少分开:
| 阶段 | 常见现象 |
|---|---|
| 解析 | xlsx 很大、公式多、空 sheet,CPU 高、内存飙 |
| 规范化 | 每行多次正则、重复加载元数据 |
| 写入 | 单行 insert、索引过多、和查询抢锁 |
| 比对 | 其实很快,除非键没建索引或在查原字符串 |
没有分段耗时,会议上只会说“去重很慢”,然后有人提议换算法。换算法解决不了 xlsx 解析。
解析:别让表格格式成为默认输入
xlsx 方便业务,不方便机器。它是压缩包 + XML,带类型猜测。同一列里又有文本又有数字时,解析器还可能把号码读成浮点。
制作时的实用选择:
- 对内推荐 csv(UTF-8),xlsx 当兼容而不是主路径
- 解析和比对拆进程,避免一个大文件把 Web 进程拖死
- 限制单文件行数和体积,超出走队列,给进度,而不是同步等到超时
科学计数法和类型破坏要进异常,不要为了“快”跳过检查。错键写得快,洗库更慢。验收包见 号码数据去重软件怎么验收。
规范化:元数据加载一次,函数保持纯
慢的实现常见于:每一行重新编译正则、每一行读一遍国家码表、在循环里写日志到同步磁盘。
快的实现很无趣:
- 元数据包进程内常驻
- 规范化函数无 I/O,方便单测和批量 map
- 先出键,再批量写库,不要 parse 一条写一条
全球规则本身的正确性,比微优化重要,见 全球号码去重系统。错误的键上建再快的索引也没有意义。
写入和比对:窄键、批量、和查询隔离
比对要快,键必须短且稳定,查询走唯一索引或等价结构。不要对 raw 做 like,不要在 SQL 里现场拼接国家码。
导入时:
- 批量提交(copy / bulk insert),不要 ORM 单条 save
- 大导入走队列,前台单条查重走另一条连接或只读副本
- 结果集流式写导出文件,不要等整包在内存里拼完
“快速”对业务有两种含义,别混:点一下查 1 个号,应接近即时;丢进 50 万行,应稳定吞吐并显示进度。用整包耗时去要求“秒级”,软件会被做成假进度条。
不建议一上来就用的加速手段
只用布隆过滤器当结论。 有假阳性,营销场景等于误删可触达号。可以当预筛,最终必须精确命中。
先分 32 个库。 规则版本、批次回滚、探针号对账会立刻变复杂。库没到千万、查询还在扫原文字段时,分库是在搬家而不是加速。
把所有数据塞进 Redis 当唯一存储。 重启、导出、审计、按来源撤回都会变难受。内存适合热键和任务锁,底库仍应落在可回放的存储上。库怎么建模见 号码数据库系统。
制作流程里把“快”写进验收,但要带负载类型
验收不要只写“80 万行 3 分钟”。写清楚:
- 单条规范化 + 查库,P95 多少
- 50 万行 csv 从上传到可导出,在无人抢资源时多少
- 同时 5 个导入 + 10 个单条查询,单条查询有没有被拖到秒级以上
后一项不过,所谓快速去重软件只在演示环境快。任务隔离的做法见 手机号码批量去重。
常见问题
哈希和数据库 unique,哪个更快?
内存哈希对已规范化的键很快,但要解决持久化和多进程。多数团队用数据库 unique 做权威,热查询再加缓存。先正确,再把热路径变窄。
多加机器能不能直接变快?
解析和单进程正则加机器没用。先看火焰图或分段日志,确认是 CPU、磁盘还是锁。架构分层见 底层架构。
怎样体验任务进度而不是只看宣传数字?
打开 在线 Demo 上传一份不算太小的样本,看状态和导出。按量级部署找 Telegram @imchat。