跳转至

对象存储:文件链路的带宽脱离与元数据解耦

文件处理不仅是“存进去”,更是一条涉及上传授权 -> 原件承载 -> 产物派生 -> 生命周期管理的长链路。

1. 带宽脱离:应用服务的解压

严禁让业务应用承载大文件上传/下载的二进制流,这会导致连接池被长时间占用,甚至拖垮整个服务的 QPS。

  • 预签名 URL (Presigned URL):业务服务仅负责鉴权与生成带时效的 Token。客户端拿着 Token 直接与对象存储(OSS/S3)交互。应用服务只出“票据”,不出“流量”。
  • 分片上传 (Multipart Upload):针对 GB 级文件,必须采用分片上传逻辑。它解决的不是存储容量,而是断点续传的容错性:哪一片失败就重传哪一片,不必重头再来。

2. 对象模型:Key 的工程直觉

在对象存储中,没有真正的“目录”,只有 Key。Key 的设计直接决定了后续检索与治理的复杂度。

  • 语义化 Key 结构:建议遵循 业务域/租户ID/对象类型/版本/文件名(e.g., kb-raw/t42/doc108/v7/original.pdf)。
  • 不可变性 (Immutability):通常建议将 Key 与文件 Hash 或 Version 绑定。不要在原地覆盖文件,而是通过数据库记录切换“当前活跃指向”,这能有效避免缓存一致性问题。

3. 产物派生:中间状态的治理

上传完成只是开始。一份 PDF 进入系统后,会派生出大量中间产物:

  • 派生路径PDF 原件 -> OCR 文本 -> 预览缩略图 -> 结构化 Chunk
  • 治理同步:中间产物必须与原件共享生命周期逻辑。如果原件因合规被物理删除,关联的 OCR 文本与预览图必须同步清理,否则就会留下数据残留(Data Residue)。

4. 元数据入库:业务真相的锚点

对象存储回答“内容在哪”,数据库回答“内容是什么”。

  • DB 记录的最小结构:必须包含 ObjectKeyFileHash(去重依据)、SizeMIMEVersionProcessingStatus
  • 不一致性检查:系统必须能容忍“对象存在但 DB 无记录”(上传中断残留)和“DB 有记录但对象缺失”(清理逻辑漏洞)。

5. 排查顺序:从票据到一致性

  1. 查票据授权:预签名 URL 是否过期?客户端 Header(如 Content-Type)是否与签名时一致?
  2. 查一致性断裂:数据库里的 ObjectKey 是否真的存在于 Bucket 中?版本是否对应?
  3. 查异步流水线:OCR 或切块 Worker 是否因为拉取对象超时而频繁重启?
  4. 查生命周期策略:是否因为错误的 Lifecycle 规则误删了仍被业务引用的历史版本?

结论对象存储是应用服务的泄压阀。好的文件架构是将二进制流从业务主链路剥离,让数据库只守元数据真相,让存储系统自理冷热归档。