
当从rest api批量拉取160万条记录时,因单次请求量过大(如25,000条/次)引发服务端超时或过载,导致503 service unavailable错误;本文提供基于游标分页与内存友好的分批处理方案,兼顾性能、稳定性和可扩展性。
当从rest api批量拉取160万条记录时,因单次请求量过大(如25,000条/次)引发服务端超时或过载,导致503 service unavailable错误;本文提供基于游标分页与内存友好的分批处理方案,兼顾性能、稳定性和可扩展性。
在高吞吐数据同步场景中,直接使用固定大小分页(如 ?limit=25000&offset=...)拉取数百万记录极易触发503错误——这并非客户端问题,而是服务端因长时间占用数据库连接、内存激增或响应超时而主动拒绝后续请求。Postman中“看似成功”往往掩盖了真实风险:它不模拟生产环境的并发压力、连接复用限制及超时策略,且缺乏错误重试与状态持久化能力。
根本解法是采用游标分页(Cursor-based Pagination) + 客户端二级分批处理:
✅ 游标分页替代偏移分页
避免 offset 导致的性能退化(数据库需跳过前N行),改用排序字段(如 created_at 或自增ID)作为游标。每次请求携带上一批最后一条记录的游标值,服务端据此查询下一页:
POST /api/v1/data
Content-Type: application/json
{
"cursor": "2024-05-20T14:22:38Z", // 上一批最后一条的 created_at
"limit": 25000
}服务端SQL示例(PostgreSQL):
SELECT * FROM records WHERE created_at > $1 ORDER BY created_at ASC LIMIT 25000;
✅ 客户端内存友好分批消费
即使单次API响应含25,000条,也不应一次性加载至内存处理。建议在应用层将每批响应再拆分为1,000条小批次进行异步写入或转换:
import requests
import time
def fetch_all_data():
cursor = None # 初始游标为空,首次请求获取最早数据
total_fetched = 0
while True:
payload = {"limit": 25000}
if cursor:
payload["cursor"] = cursor
resp = requests.post("https://api.example.com/data", json=payload, timeout=60)
if resp.status_code != 200:
raise Exception(f"API error: {resp.status_code} - {resp.text}")
data_batch = resp.json()["data"]
if not data_batch:
break
# 二次分批:每1000条为一组处理,降低内存峰值
for i in range(0, len(data_batch), 1000):
batch = data_batch[i:i+1000]
process_batch(batch) # 如写入DB、发送Kafka等
total_fetched += len(batch)
# 更新游标:取本批最后一条的排序字段值
cursor = data_batch[-1]["created_at"]
print(f"Fetched {total_fetched} records...")
# 可选:轻量级节流,避免压垮服务端
time.sleep(0.1)
def process_batch(batch):
# 示例:批量插入数据库(使用参数化查询防注入)
pass⚠️ 关键注意事项
- 服务端必须支持游标分页:确保API文档明确说明游标字段、排序规则及空游标行为(如首次请求不传cursor即返回最早数据);
- 时间精度要足够:若按created_at分页,需确认数据库时间精度(毫秒级)并避免同一毫秒内多条记录——此时应追加唯一字段(如id)作为二级游标:WHERE (created_at, id) > ($1, $2);
- 幂等性与断点续传:记录已处理的最新游标值到可靠存储(如Redis或DB),程序崩溃后可从中断处恢复;
- 超时与重试策略:设置合理timeout(建议30–60s),对503/504错误实施指数退避重试(如retry_after=2^attempt * 1s);
- 监控与告警:追踪单次请求耗时、游标推进速度、失败率,及时发现服务端性能拐点。
综上,503错误本质是系统设计失配的信号。放弃“大而全”的单次请求思维,转向“小而稳”的游标驱动流式拉取,辅以客户端精细化批处理,方能在海量数据场景中实现高可用、低延迟、易运维的数据同步链路。










