文件存储方案的选择:本地存储、对象存储与 CDN 的协作

发布时间:2026/7/18 23:13:32
文件存储方案的选择:本地存储、对象存储与 CDN 的协作 文件存储方案的选择本地存储、对象存储与 CDN 的协作一、文件存储不是「存到硬盘上」就完事独立产品在早期,文件存储很简单:用户上传的头像存到服务器的public/uploads/目录,代码里引用这个路径,搞定。但随着用户数量增长和文件数量增多,本地存储的局限性开始显现:服务器磁盘满了、文件访问占用了应用带宽、服务器迁移时需要手动拷贝所有文件、没有备份和冗余。文件存储的选型,核心考虑三个维度:容量(能存多少)、访问速度(多快能获取到文件)、可用性(文件会不会丢失)。graph TD A[文件存储方案] -- B[本地存储br/服务器磁盘] A -- C[对象存储br/S3 / R2 / OSS] A -- D[CDNbr/Cloudflare / CDN77] B -- E[适合: 临时文件br/不适合: 用户上传文件] C -- F[适合: 用户上传文件br/备份/冗余/无限容量] D -- G[适合: 静态资源加速br/全球分发/降低延迟] F -- G style C fill:#c8e6c9 style D fill:#e3f2fd二、本地存储:何时够用,何时不够本地存储(服务器的文件系统)的优势是零延迟(本地磁盘访问)、零外部依赖(不需要配置第三方服务)、免费(你有多少磁盘就存多少)。在以下场景中,本地存储是合理的选择:临时文件:缓存的渲染结果、导出的报告——这些文件不需要持久化,丢失了可以重新生成。应用配置文件:很少修改,只在部署时更新——用 Git 管理,部署时带上。开发和测试环境——不需要引入云服务,本地磁盘就够了。本地存储的不足:无法水平扩展(多台服务器之间文件不共享,除非用 NFS 等共享文件系统);没有内置的备份和冗余(服务器磁盘故障,文件全丢);占用应用服务器的磁盘和带宽。当你的产品需要保存用户的文件(头像、上传的文档、生成的图片)时,就应该从本地存储迁移到对象存储。三、对象存储:独立文件的最佳归宿对象存储(如 AWS S3、Cloudflare R2、阿里云 OSS、Backblaze B2)是为「存储和分发大量文件」设计的服务。它的核心特性:无限容量(理论上),按实际使用量付费,不需要提前规划磁盘大小。高可用性和数据冗余,文件默认在多个数据中心备份(通常 99.999999999% 的持久性)。内置的访问控制和分发能力,可以直接通过 URL 访问文件,不需要经过应用服务器中转。生命周期管理,可以自动将旧文件转移到更便宜的存储层(如 Glacier),或自动删除过期文件。对象存储的关键设计:不通过应用服务器中转文件。用户上传文件时,前端直接上传到对象存储(通过 Presigned URL 或临时凭证),不经过你的服务器。用户下载文件时,也是直接从对象存储的 URL 获取。这样做,文件的存储和传输完全不占用应用服务器的带宽和 CPU。sequenceDiagram participant U as 用户 participant F as 前端 participant A as 应用服务器 participant S as 对象存储 U-F: 选择文件上传 F-A: 请求上传凭证 A-A: 生成 Presigned URL A--F: 返回临时上传URL F-S: 直接上传文件br/(不经过应用服务器) S--F: 上传成功 F-A: 通知: 文件已上传br/(发送文件URL) A-A: 存储文件URL到数据库四、CDN:加速全球用户访问文件存储 (对象存储) CDN 是标准组合。对象存储解决了「文件存在哪里」的问题,CDN 解决了「用户从多快的地方拿到文件」的问题。CDN 将文件分发到全球边缘节点,用户从距离最近的节点获取文件,延迟最低。对于独立产品,如果用户主要在中国,对象存储选中国大陆地域 国内的 CDN 服务;如果用户分布全球,可以选 Cloudflare R2(对象存储) Cloudflare CDN(自带),实现全球覆盖。CDN 的配置要点:缓存策略:为不同类型文件设置不同的Cache-Control头。静态资源(JS/CSS/字体)可以缓存一年(max-age31536000, immutable),头像可以缓存一天,生成的内容可以缓存一小时。缓存失效:当文件更新时,需要让 CDN 刷新缓存。可以通过文件名哈希化(file.abc123.js)来绕过缓存失效——新文件名 新 URL,CDN 自动回源获取新文件。防盗链:如果你不希望文件被外部网站直接引用,可以配置 CDN 的 Referer 白名单或 Token 鉴权。五、总结文件存储方案的选择,核心原则是:把文件和应用的运行分离。应用服务器不存储用户文件,文件不经过应用服务器传输。这样你的服务器只需要处理业务逻辑,不需要分心管理文件。对于独立产品,从对象存储开始是一种低成本的「正确做法」——Cloudflare R2 免流量费,AWS S3 和阿里云 OSS 的成本也很低(按 GB 付费)。在对象存储之上,如果需要服务全球用户,加上 CDN 加速;如果做好文件名哈希化,CDN 缓存几乎不需要手动管理。本地存储只在临时文件、配置文件和开发环境中使用。一旦涉及到「用户上传的文件」,就迁移到对象存储。这个决策在产品早期做好,比产品增长后再迁移节省大量时间和精力。