df51f84ab5
README 更新: - 移除顶部 header.png 横幅图片 - 新增「附录知识库」板块,以 3×3 网格展示 9 大知识领域精选内容 - 附录链接指向部署版网站 (datawhalechina.github.io) - 阶段表格新增「附录」行,突出 80+ 交互式专题 - 章节标题「新手入门 & PM」简化为「零基础入门」 - News 新增 2026-02-25 附录知识库更新条目 新增交互组件: - 异步任务队列 (async-task-queues) 演示组件 - 文件存储 (file-storage) 演示组件 - 项目架构 (project-architecture) 演示组件 - 限流与背压 (rate-limiting) 演示组件 - 搜索引擎 (search-engines) 演示组件 - 计算机基础: AppLaunch/BiosUefi/OSBoot 等启动流程演示组件 新增附录文档: - 前端项目架构 (frontend-project-architecture.md) - 后端项目架构 (backend-project-architecture.md) 内容优化: - 算法思维、数据结构、编程语言、调试艺术等多篇附录内容更新 - HTML/CSS 布局、请求旅程等前后端文档完善 - 附录索引页 (index.md) 同步更新
163 lines
7.5 KiB
Markdown
163 lines
7.5 KiB
Markdown
# 文件存储与对象存储
|
||
|
||
::: tip 前言
|
||
**用户上传了一张头像,你把它存在服务器的 `/uploads` 目录下——然后服务器磁盘满了,或者你加了第二台服务器,用户发现头像时有时无。** 文件存储看似简单,但在分布式环境下却是一个需要认真对待的架构问题。对象存储就是互联网时代解决这个问题的标准答案。
|
||
:::
|
||
|
||
**这篇文章会带你学什么?**
|
||
|
||
学完这章后,你将获得:
|
||
|
||
- **存储类型认知**:理解块存储、文件存储、对象存储的区别和适用场景
|
||
- **对象存储核心概念**:掌握 Bucket、Object、Key、Pre-signed URL 等核心概念
|
||
- **上传方案设计**:学会客户端直传 vs 服务端中转的方案选型
|
||
- **CDN 加速原理**:理解 CDN 如何加速静态资源的全球分发
|
||
- **最佳实践**:掌握文件命名、权限控制、生命周期管理等实战技巧
|
||
|
||
| 章节 | 内容 | 核心概念 |
|
||
|-----|------|---------|
|
||
| **第 1 章** | 存储类型对比 | 块存储、文件存储、对象存储 |
|
||
| **第 2 章** | 对象存储核心概念 | Bucket、Object、Key、元数据 |
|
||
| **第 3 章** | 文件上传方案 | 客户端直传、Pre-signed URL |
|
||
| **第 4 章** | CDN 加速 | 边缘节点、缓存策略、回源 |
|
||
| **第 5 章** | 最佳实践 | 命名规范、权限、生命周期 |
|
||
|
||
---
|
||
|
||
## 0. 全景图:为什么不能把文件存在服务器本地?
|
||
|
||
刚开始做项目时,把用户上传的文件存在服务器本地目录是最直觉的做法。但随着项目发展,你会遇到一系列问题:
|
||
|
||
- **磁盘空间有限**:服务器磁盘总会满,扩容麻烦
|
||
- **多服务器不共享**:负载均衡后,用户请求可能打到不同服务器,文件找不到
|
||
- **没有备份**:服务器挂了,文件就丢了
|
||
- **没有 CDN**:全球用户访问同一台服务器,速度慢
|
||
|
||
::: tip 对象存储的核心价值
|
||
对象存储(如 AWS S3、阿里云 OSS)解决了所有这些问题:**容量无限、全球可访问、自动备份、天然支持 CDN**。它已经成为互联网应用存储文件的事实标准。
|
||
:::
|
||
|
||
---
|
||
|
||
## 1. 存储类型对比:块、文件、对象
|
||
|
||
计算机世界有三种主要的存储方式,它们解决不同层次的问题。
|
||
|
||
<FileStorageTypeDemo />
|
||
|
||
| 维度 | 块存储 | 文件存储 | 对象存储 |
|
||
|------|--------|---------|---------|
|
||
| 数据单位 | 固定大小的块 | 文件 + 目录 | 对象(Key-Value) |
|
||
| 访问协议 | iSCSI/FC | NFS/SMB | HTTP REST API |
|
||
| 性能 | 最高(毫秒级) | 中等 | 较低(但够用) |
|
||
| 扩展性 | 有限 | 中等 | 近乎无限 |
|
||
| 成本 | 最高 | 中等 | 最低 |
|
||
| 典型场景 | 数据库 | 共享文件 | 图片/视频/备份 |
|
||
|
||
::: tip 简单记忆
|
||
- **块存储**像硬盘——给数据库用
|
||
- **文件存储**像网络共享文件夹——给多台服务器共享配置用
|
||
- **对象存储**像网盘——给用户上传的图片、视频用
|
||
:::
|
||
|
||
---
|
||
|
||
## 2. 对象存储核心概念
|
||
|
||
对象存储的数据模型非常简单:**Bucket(桶)** 是容器,**Object(对象)** 是文件,每个对象通过唯一的 **Key(键)** 来标识。
|
||
|
||
```
|
||
my-app-bucket/ ← Bucket(桶)
|
||
├── avatars/user-123.jpg ← Object Key
|
||
├── avatars/user-456.png ← Object Key
|
||
├── reports/2024/q1-report.pdf ← Object Key("目录"只是 Key 的前缀)
|
||
└── uploads/temp/file.zip ← Object Key
|
||
```
|
||
|
||
| 概念 | 说明 | 示例 |
|
||
|------|------|------|
|
||
| Bucket | 存储容器,全局唯一命名 | `my-app-prod`、`company-assets` |
|
||
| Object | 存储的文件本体 + 元数据 | 一张图片、一个 PDF |
|
||
| Key | 对象的唯一标识符 | `avatars/user-123.jpg` |
|
||
| 元数据 | 对象的附加信息 | Content-Type、自定义标签 |
|
||
| ACL | 访问控制列表 | public-read、private |
|
||
| Pre-signed URL | 临时授权访问链接 | 有效期 15 分钟的上传/下载链接 |
|
||
|
||
::: tip 对象存储没有真正的"目录"
|
||
`avatars/user-123.jpg` 中的 `avatars/` 不是目录,只是 Key 的前缀。对象存储是扁平结构,所有对象在同一层级。控制台显示的"文件夹"只是按前缀分组的视觉效果。
|
||
:::
|
||
|
||
---
|
||
|
||
## 3. 文件上传方案:谁来传文件?
|
||
|
||
文件上传有两种主流方案:服务端中转和客户端直传。对于大多数场景,**客户端直传**是更优的选择。
|
||
|
||
<FileUploadFlowDemo />
|
||
|
||
::: tip 客户端直传的优势
|
||
1. **节省服务器带宽**:文件不经过你的服务器,直接到 OSS
|
||
2. **避免超时**:大文件上传不会触发 Nginx/网关的超时限制
|
||
3. **降低服务器负载**:服务器只需要签发凭证,不需要处理文件流
|
||
4. **支持断点续传**:OSS 原生支持分片上传,前端可以实现断点续传
|
||
|
||
实现步骤:前端请求后端获取 Pre-signed URL → 前端用这个 URL 直接上传到 OSS → OSS 回调通知后端
|
||
:::
|
||
|
||
---
|
||
|
||
## 4. CDN 加速:让全球用户都快
|
||
|
||
当你的用户遍布全球时,从单一源站下载文件会很慢。CDN(Content Delivery Network)通过在全球部署边缘节点,将文件缓存到离用户最近的节点,大幅降低访问延迟。
|
||
|
||
<CDNAccelerationDemo />
|
||
|
||
| CDN 概念 | 说明 |
|
||
|---------|------|
|
||
| 边缘节点 | 分布在全球各地的缓存服务器 |
|
||
| 回源 | 边缘节点没有缓存时,向源站请求文件 |
|
||
| 缓存命中率 | 请求被边缘节点直接响应的比例,越高越好 |
|
||
| TTL | 缓存有效期,过期后需要重新回源 |
|
||
| 缓存刷新 | 主动清除边缘节点的缓存,让新文件生效 |
|
||
|
||
::: tip CDN 最佳实践
|
||
- **文件名加 hash**:`logo.a3f2b1.png` 而不是 `logo.png`,这样更新文件时不需要刷新缓存
|
||
- **设置合理的 TTL**:静态资源(JS/CSS/图片)设长 TTL(1年),HTML 设短 TTL(5分钟)
|
||
- **开启 Gzip/Brotli 压缩**:文本类资源压缩后体积减少 60-80%
|
||
:::
|
||
|
||
---
|
||
|
||
## 5. 最佳实践
|
||
|
||
| 实践 | 说明 | 示例 |
|
||
|------|------|------|
|
||
| Key 命名规范 | 用有意义的前缀组织文件 | `{type}/{date}/{uuid}.{ext}` |
|
||
| 避免热点 Key | 不要用递增数字开头 | 用 UUID 或 hash 前缀 |
|
||
| 权限最小化 | Bucket 默认 private | 只对需要公开的文件设置 public-read |
|
||
| 生命周期规则 | 自动清理过期文件 | 临时文件 7 天后自动删除 |
|
||
| 跨域配置 | 前端直传需要配置 CORS | 允许你的域名 PUT/POST |
|
||
| 服务端加密 | 敏感文件开启 SSE | SSE-S3 或 SSE-KMS |
|
||
|
||
---
|
||
|
||
## 总结
|
||
|
||
文件存储是每个 Web 应用都会遇到的基础问题。对象存储以其无限容量、低成本、高可用的特性,成为了互联网应用的标准选择。
|
||
|
||
回顾本章的关键要点:
|
||
|
||
1. **三种存储类型**:块存储给数据库、文件存储给共享、对象存储给用户文件
|
||
2. **对象存储模型**:Bucket + Key + Object,扁平结构,HTTP API 访问
|
||
3. **客户端直传**:Pre-signed URL 方案,文件不经过服务器,高效省资源
|
||
4. **CDN 加速**:边缘节点缓存 + 文件名 hash,让全球用户都快
|
||
5. **安全与管理**:权限最小化、生命周期规则、服务端加密
|
||
|
||
## 延伸阅读
|
||
|
||
- [AWS S3 开发者指南](https://docs.aws.amazon.com/s3/) - 对象存储的标杆文档
|
||
- [阿里云 OSS 最佳实践](https://help.aliyun.com/document_detail/31853.html) - 国内最常用的对象存储
|
||
- [MinIO 文档](https://min.io/docs/minio/linux/index.html) - 开源的 S3 兼容对象存储
|
||
- [Cloudflare R2](https://developers.cloudflare.com/r2/) - 零出口费用的对象存储
|
||
- [Pre-signed URL 详解](https://docs.aws.amazon.com/AmazonS3/latest/userguide/using-presigned-url.html) - 客户端直传的核心机制
|