批量操作

一个电商客户的请求

那天下午,我收到了一封加急邮件。

Inbox
From: 电商技术负责人
To:
Time: 周二 14:20
Subject: 【紧急】双十一促销需要批量短链接

你好,我是某电商的技术负责人。我们马上要做双十一大促,有 5000 个产品链接需要缩短,用于短信营销。每条短信按字符计费,长链接太贵了。

能不能今天搞定?我们明天就要开始发短信了。

5000 个链接。我的 API 一次只能处理一个。

当前架构
生产版:可运营短链接平台
创建、跳转、统计、安全和管理链路各自独立,又围绕短码状态协同。
用户入口
短链域名
管理后台
开放 API
核心服务
创建服务
跳转服务
链接管理
数据能力
点击事件
实时统计
离线报表
治理能力
内容审核
风控拦截
申诉复核
存储
MySQL
Redis
对象/分析存储

第一版:同步批量接口

最快的方案

客户催得紧,我决定先出一个最快的方案。

落地思路

  • 这里省略具体语法,只保留设计层面的职责边界。
  • 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。

问题很快暴露

客户分 5 批提交了 5000 个链接。每批 1000 个,平均耗时 15 秒

“15 秒?太慢了!我们点提交后页面一直在转圈,还以为挂了。”

我查了一下瓶颈:1000 次数据库 INSERT,每次约 15ms,总计 15 秒。


优化:事务批量插入

把 1000 次提交合并为 1 次

“原来每次 INSERT 都是一次磁盘写入。如果把 1000 条打包成一次事务呢?”

落地思路

  • 这里省略具体语法,只保留设计层面的职责边界。
  • 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。

效果

方案1000 条耗时原因
逐条 INSERT15 秒1000 次磁盘写入
事务批量1.5 秒1 次磁盘写入

“10 倍提升,客户满意了。“


CSV 导入

客户的第二个需求

“能不能支持 CSV 文件导入?我们运营团队只会用 Excel。”

落地思路

  • 这里省略具体语法,只保留设计层面的职责边界。
  • 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。

CSV 格式说明

我写了个简单的文档给客户:

# CSV 文件格式

## 必需列
- url(或 URL、链接)

## 可选列
- title(链接标题)
- tag(标签,用于分组管理)

## 示例
url,title,tag
https://example.com/product/1,iPhone 15,手机
https://example.com/product/2,MacBook Pro,电脑
https://example.com/product/3,AirPods,耳机

更大的客户来了

新问题:10 万条链接

一个月后,一个更大的客户找上门。

“我们有 10 万条 链接需要缩短,用于全渠道营销推广。”

10 万条。即使事务优化后,也需要 150 秒。HTTP 请求早就超时了。

“我意识到,同步方案的天花板到了。“


异步处理:Celery 任务队列

架构改造

“我花了一个周末引入了 Celery 异步任务队列。“

┌──────────┐     ┌──────────┐     ┌──────────┐
│  客户端   │────▶│  API 服务 │────▶│  Redis   │  ← 任务队列
└──────────┘     └──────────┘     └──────────┘


                                 ┌──────────┐
                                 │  Worker  │  ← 后台处理
                                 └──────────┘


                                 ┌──────────┐
                                 │  MySQL   │
                                 └──────────┘

提交任务

落地思路

  • 这里省略具体语法,只保留设计层面的职责边界。
  • 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。

Worker 处理

落地思路

  • 这里省略具体语法,只保留设计层面的职责边界。
  • 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。

效果

方案10 万条耗时客户体验
同步接口150 秒(超时)❌ 页面卡死
异步任务~30 秒(后台)✅ 秒级响应,后台处理

进度追踪

查询接口

“客户提交后总想知道进度。我加了一个查询接口。”

落地思路

  • 这里省略具体语法,只保留设计层面的职责边界。
  • 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。

客户端轮询

交互要点

  • 前端逻辑重点是展示任务状态、错误原因和下一步操作。
  • 轮询或进度刷新要有节制,避免给后端制造新的压力。

批量删除和更新

批量删除

“后来客户又提出:大促结束了,那些活动链接能不能批量删除?”

落地思路

  • 这里省略具体语法,只保留设计层面的职责边界。
  • 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。

批量更新

落地思路

  • 这里省略具体语法,只保留设计层面的职责边界。
  • 读这段时重点看:输入是什么、系统做哪些判断、状态如何变化、失败时如何兜底。

成本分析

“引入 Celery 后,我算了一笔账。“

组件月成本说明
额外 Redis 实例¥40/月Celery broker
Worker 服务器¥60/月2 核 4G
合计¥100/月

“多花了 ¥100/月,但换来了企业客户的满意度。这个投入值不值?看收入就知道了——批量功能上线后,企业客户付费转化提升了 30%。”