本节摘要:S3 和 RDS 是 AWS 上用得最多的两个数据服务——前者是对象存储的"行业标准",后者是托管关系数据库的"事实标杆"。本节用真实工程链路"建 S3 桶 → 配生命周期 → 上传 → 生成预签名 URL"和"启 RDS 多可用区 → 备份 → 调优连接池"展开。学完本节,你应能用 AWS CLI 独立跑通一个最小可用的"应用 + 对象存储 + 数据库"三件套架构。
阅读完本节,你应当能够:
很多新手把 S3 当作"无限大的网盘"用,结果在性能、成本、权限三方面都踩坑。
举一个反例:某公司 2021 年把所有产品图片放 S3,没配生命周期规则。3 年后桶里有 800TB 数据,其中 700TB 是 1 年前上传后再没访问过的。月存储费 7 万元——但其实这 700TB 应该早就降级到 Glacier(每 GB 0.004 USD/月,是标准存储的 1/25)。
正解:S3 的"对象"是不可变的大文件,配生命周期规则是头号降本技巧。没配生命周期规则的 S3 桶,几乎一定在烧钱。
# 创建 S3 桶(注意桶名全球唯一) aws s3 mb s3://my-app-images-2026 # 启用版本控制 aws s3api put-bucket-versioning \ --bucket my-app-images-2026 \ --versioning-configuration Status=Enabled # 配置生命周期规则 cat > lifecycle.json <<EOF { "Rules": [ { "ID": "downgrade-old-images", "Status": "Enabled", "Prefix": "user-original/", "Transitions": [ { "Days": 30, "StorageClass": "STANDARD_IA" }, { "Days": 90, "StorageClass": "GLACIER" }, { "Days": 365, "StorageClass": "DEEP_ARCHIVE" } ] } ] } EOF aws s3api put-bucket-lifecycle-configuration \ --bucket my-app-images-2026 \ --lifecycle-configuration file://lifecycle.json # 上传文件 aws s3 cp ./local-image.jpg s3://my-app-images-2026/user-original/ # 列出桶内对象 aws s3 ls s3://my-app-images-2026/ --recursive --summarize
# 生成 1 小时有效的下载链接 aws s3 presign s3://my-app-images-2026/user-original/photo.jpg \ --expires-in 3600 # 生成 1 小时有效的上传链接(PUT) aws s3 presign s3://my-app-images-2026/user-upload/tmp.jpg \ --expires-in 3600 \ --method put
预签名 URL 的真实价值:把"上传/下载授权"从"长期 AccessKey"换成"短时 URL"——前端不需要任何凭证。这是云上文件分发的标准做法。
# 创建 RDS 子网组(多可用区) aws rds create-db-subnet-group \ --db-subnet-group-name my-app-subnets \ --db-subnet-group-description "App subnets" \ --subnet-ids subnet-aaa subnet-bbb subnet-ccc # 创建 RDS MySQL 多可用区实例 aws rds create-db-instance \ --db-instance-identifier my-app-db \ --db-instance-class db.t3.medium \ --engine mysql \ --engine-version 8.0.32 \ --master-username admin \ --master-user-password 'MySecureP@ssw0rd!' \ --allocated-storage 100 \ --storage-type gp3 \ --multi-az \ --db-subnet-group-name my-app-subnets \ --vpc-security-group-ids sg-database \ --backup-retention-period 7 \ --preferred-backup-window "03:00-04:00" \ --preferred-maintenance-window "Mon:00:00-Mon:01:00" \ --no-deletion-protection # 创建读副本 aws rds create-db-instance-read-replica \ --db-instance-identifier my-app-db-replica \ --source-db-instance-identifier my-app-db \ --db-instance-class db.t3.medium
| 优化项 | 方法 | 效果 |
|---|---|---|
| 大文件分片上传 | multipart upload,单文件 >100MB 时启用 | 失败重传粒度小、速度提升 3-5 倍 |
| CloudFront CDN 加速 | 静态资源走 CloudFront 边缘节点 | 首字节延迟从 200ms 降到 20ms |
| 请求频率优化 | 合并小文件、缓存列表结果 | 减少 GET 请求次数,节省 API 费 |
| 工具 | 看什么 | 何时用 |
|---|---|---|
| Performance Insights | DB Load、等待事件、SQL 统计 | 性能问题定位的首选 |
| 慢查询日志 | slow_query_log、long_query_time |
找执行慢的 SQL |
| Enhanced Monitoring | 进程级 CPU、内存、磁盘 IO | OS 层瓶颈排查 |
真实反例:某 RDS MySQL 实例 CPU 持续 90%,DBA 不知道是哪条 SQL。开了 Performance Insights 后发现是 SELECT * FROM orders WHERE user_id = ? 走了全表扫描(user_id 没建索引)。加索引后 CPU 降到 10%。Performance Insights 是 RDS 调优的必备工具。
RDS 的最大连接数有上限(db.t3.medium 默认 max_connections=150)。应用层忘记关连接 = 数据库连接数耗尽。
调优方法:
DBConnections 指标,超过 80% 触发告警。| 反例 | 后果 | 正解 |
|---|---|---|
| 不配 S3 生命周期 | 月存储费 5 倍于实际需要 | 配 IA/Glacier 转换 |
| S3 桶开公开读 | 数据泄露 | 桶策略 + ACL 双层防护 |
| 数据库密码写在代码里 | 泄露后无法追责 | 用 Secrets Manager + IAM 角色 |
| 业务直连 RDS,没用连接池 | 连接数耗尽 | HikariCP + RDS Proxy |
| RDS 没开多可用区 | 单点故障 | multi-az 参数必须开 |
| 慢查询没建索引 | CPU 持续 90% | 慢查询日志 + Performance Insights |
⚠️ 常见坑:"S3 是 11 个 9 的持久性" ≠ "数据不会丢"。11 个 9 是"云厂商基础设施"的持久性,但你的 AccessKey 泄露、生命周期规则写错、桶策略公开读——这些是用户配置错误,不在 11 个 9 覆盖范围内。S3 数据丢失的 80% 案例都是用户配置错误,不是 AWS 故障。
💡 关键直觉:S3 的成本治理核心是"生命周期规则";RDS 的性能治理核心是"慢查询日志 + 索引 + 连接池"。把这两件事做扎实,AWS 数据层就稳了。
下一节切到 AWS 网络与监控——VPC 实战和 CloudWatch 告警闭环。