简介
Amazon Simple Storage Service(S3)是 AWS 的对象存储服务,用于存储任意类型的文件(备份、静态资源、日志等),按实际使用量计费。
核心概念:
- Bucket:存储桶,名字在全球所有 AWS 账号、所有区域共享同一命名空间,全球唯一
- Object:对象,即一个文件,由 Key(路径)+ 数据 + 元数据组成
- Key:对象的唯一标识符,形如
path/to/file.txt,只需在桶内唯一(S3 本身是扁平结构,/只是命名惯例)
| 概念 | 唯一性范围 |
|---|---|
| Bucket 名字 | 全球唯一(跨账号、跨区域) |
| Object Key | 桶内唯一 |
| 数据存储位置 | 只在创建时指定的区域 |
区域与高可用
Bucket 在创建时必须指定区域(如 ap-northeast-1 东京),之后无法更改,数据默认只存在于该区域。
S3 在同一个区域内会把数据自动分散到至少 3 个可用区(AZ),设计耐久性是 99.999999999%(11 个 9)。区域内某个数据中心故障,数据不受影响。
如果整个区域发生故障(极罕见),默认情况下无法从其他区域访问该桶的数据。如需跨区域容灾,要显式配置 Cross-Region Replication(CRR):
东京桶(主) --CRR--> 新加坡桶(副本)
CRR 要求两个桶都开启版本控制(Versioning),并配置 IAM Role 授权跨桶复制权限。
实践建议:用于数据库备份等灾难恢复场景,单区域已经足够,无需配置 CRR。若担心区域级故障,更简单的做法是用
aws s3 sync定期同步到另一个区域,或下载到本地存一份。
常用命令
# 列出所有 bucket
aws s3 ls
# 列出 bucket 内的对象
aws s3 ls s3://my-bucket/
aws s3 ls s3://my-bucket/prefix/
# 上传文件
aws s3 cp local-file.txt s3://my-bucket/path/file.txt
# 下载文件
aws s3 cp s3://my-bucket/path/file.txt local-file.txt
# 同步目录(本地 → S3)
aws s3 sync ./local-dir s3://my-bucket/prefix/
# 同步目录(S3 → 本地)
aws s3 sync s3://my-bucket/prefix/ ./local-dir
# 删除对象
aws s3 rm s3://my-bucket/path/file.txt
# 删除 prefix 下所有对象
aws s3 rm s3://my-bucket/prefix/ --recursive
Bucket 管理
# 创建 bucket(指定区域)
aws s3api create-bucket \
--bucket my-bucket \
--region ap-northeast-1 \
--create-bucket-configuration LocationConstraint=ap-northeast-1
# 删除 bucket(必须先清空)
aws s3 rm s3://my-bucket --recursive
aws s3api delete-bucket --bucket my-bucket
# 查看 bucket 所在区域
aws s3api get-bucket-location --bucket my-bucket
生命周期策略(Lifecycle)
用于自动过期或转换存储类型,节省费用。
{
"Rules": [
{
"ID": "expire-old-backups",
"Status": "Enabled",
"Filter": {},
"Expiration": {
"Days": 30
}
}
]
}
# 应用生命周期规则
aws s3api put-bucket-lifecycle-configuration \
--bucket my-bucket \
--lifecycle-configuration file://lifecycle.json
# 查看当前规则
aws s3api get-bucket-lifecycle-configuration --bucket my-bucket
IAM 权限控制
最小权限策略示例(只允许写入指定 bucket)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject",
"s3:ListBucket",
"s3:DeleteObject"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}
]
}
EC2 通过 IAM Instance Profile 访问 S3
EC2 实例绑定 IAM Role 后,实例内的程序可以直接使用 aws CLI 或 SDK 访问 S3,无需配置 Access Key。
# 在绑定了 Instance Profile 的 EC2 上,直接可用
aws s3 ls s3://my-bucket/
费用
S3 费用分三块独立计费,以东京区域(ap-northeast-1)标准存储类为例:
存储费用
按实际存储的数据量每月计费:
| 存储类 | 费用 | 适用场景 |
|---|---|---|
| Standard(标准) | $0.025 / GB / 月 | 频繁访问 |
| Standard-IA(低频访问) | $0.0138 / GB / 月 | 每月访问几次 |
| Glacier Instant Retrieval | $0.005 / GB / 月 | 归档,毫秒级取回 |
| Glacier Flexible Retrieval | $0.0045 / GB / 月 | 归档,分钟~小时取回 |
请求费用
每次 API 调用单独计费:
| 操作 | 费用 |
|---|---|
| PUT / COPY / POST(写) | $0.0047 / 1000 次 |
| GET / SELECT(读) | $0.00037 / 1000 次 |
| LIST | $0.0047 / 1000 次 |
| DELETE | 免费 |
数据传出费用
| 流量方向 | 费用 |
|---|---|
| 互联网 → S3(上传) | 免费 |
| S3 → 同区域 EC2 | 免费 |
| S3 → 互联网(下载) | $0.114 / GB |
| S3 → 其他 AWS 区域 | $0.02 / GB |
备份上传免费,平时不下载则流量费为零,只有恢复数据时才产生下载费用。
实际费用估算
以 enx-api 备份场景为例(DB 文件 10 MB,保留 30 天,每日备份一次):
| 费用项 | 计算 | 金额 |
|---|---|---|
| 存储 | 300 MB × $0.025/GB | ~$0.0075 / 月 |
| PUT 请求 | 30 次 × $0.0047/1000 | ~$0.00014 / 月 |
| 流量 | 上传免费 | $0 |
| 合计 | < $0.01 / 月 |
阻止公开访问
创建 bucket 后建议立即开启全部 Block Public Access 选项,防止误配置导致数据泄露:
aws s3api put-public-access-block \
--bucket my-bucket \
--public-access-block-configuration \
"BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
实践案例:SQLite 数据库每日备份
enx-api 项目使用 systemd timer + aws cli 将 SQLite 数据库每日自动备份到 S3:
# 热备份(DB 使用中也安全)
sqlite3 /var/lib/enx-api/enx.db ".backup '/tmp/backup.db'"
# 上传到 S3
aws s3 cp /tmp/backup.db s3://wiloon-enx-backup/enx-api-$(date +%Y%m%d-%H%M%S).db
Bucket 配置了 30 天生命周期自动过期。详见 enx-api 数据库备份文档。