Amazon S3 Vectors GA 实测:40 倍 Scale 提升 + Per-Index 加密 + 性能基准¶
Lab 信息
- 难度: ⭐⭐ 中级
- 预估时间: 30 分钟
- 预估费用: < $0.10(含清理)
- Region: us-east-1
- 最后验证: 2026-03-26
前置阅读
本文是 S3 Vectors Preview 实战 的 GA 升级篇。如果你还不了解 S3 Vectors 的基础概念(Vector Bucket / Index / Vector 三层架构、元数据过滤语法等),建议先阅读 Preview 篇。本文聚焦 Preview → GA 的变化,不重复基础内容。
背景¶
2025 年 7 月,AWS 发布 Amazon S3 Vectors Preview,我们第一时间做了动手测试。Preview 期间用户创建了超过 25 万个索引,写入超过 400 亿向量,执行超过 10 亿次查询。
2025 年 12 月,S3 Vectors 正式 GA,带来了一系列重大升级。最核心的变化是 单索引向量容量从 5000 万提升到 20 亿(40 倍),这意味着大多数场景不再需要分片索引。同时新增了 Per-Index KMS 加密、资源标签、CloudFormation 支持等生产级功能。
本文通过实测验证 GA 版本的新能力,重点回答三个问题:
- Scale 变化实际感受如何? Top-K 从 30 提升到 100,实测延迟变化?
- Per-Index KMS 加密怎么配? 多租户隔离的新姿势
- GA 延迟 vs Preview 延迟? 官方声称频繁查询可达 ~100ms,实测如何?
Preview → GA 关键变化一览¶
| 指标 | Preview | GA | 变化 |
|---|---|---|---|
| 每索引最大向量数 | 5000 万 | 20 亿 | 40x ↑ |
| Top-K 结果数 | 30 | 100 | 3.3x ↑ |
| Region 数量 | 5 | 14 | +9 Regions |
| 写入吞吐 | 未公开 | 1,000 PUT TPS | 新指标 |
| 频繁查询延迟 | sub-second | ~100ms | 优化 |
| 每向量 metadata keys | 未明确 | 50 | 新限制 |
| Per-Index KMS 加密 | ❌ | ✅ | 新功能 |
| 资源标签(Tagging) | ❌ | ✅ | 新功能 |
| CloudFormation | ❌ | ✅ | 新功能 |
| AWS PrivateLink | ❌ | ✅ | 新功能 |
| Bedrock KB 集成 | Preview | ✅ GA | 正式发布 |
| OpenSearch 集成 | Preview | ✅ GA | 正式发布 |
前置条件¶
- AWS 账号
- AWS CLI v2(含
s3vectors子命令) - Python 3 + Boto3
- IAM 权限:
s3vectors:*、kms:CreateKey、kms:PutKeyPolicy(测试 KMS 加密需要)
动手实践¶
Step 1: 创建 Vector Bucket 和 Index¶
# 创建向量 bucket
aws s3vectors create-vector-bucket \
--vector-bucket-name s3v-ga-demo \
--region us-east-1
# 创建基础索引(SSE-S3 默认加密)
aws s3vectors create-index \
--vector-bucket-name s3v-ga-demo \
--index-name idx-basic \
--data-type float32 \
--dimension 1024 \
--distance-metric cosine \
--region us-east-1
Step 2: 配置 Per-Index KMS 加密(GA 新功能)¶
这是 GA 版本最重要的企业级新功能之一。Preview 期间加密只能在 bucket 级别设置,GA 允许每个 index 使用独立的 KMS key,支持多租户隔离。
首先创建 KMS key:
KEY_ID=$(aws kms create-key \
--description 's3v-ga-test-key' \
--region us-east-1 \
--query 'KeyMetadata.KeyId' \
--output text)
echo "Key ID: $KEY_ID"
配置 KMS key policy(关键步骤):
踩坑:必须授权 S3 Vectors 服务主体
创建 per-index KMS 加密的索引时,KMS key 必须有 resource policy 授权给 indexing.s3vectors.amazonaws.com 服务主体。否则会报 AccessDeniedException: Insufficient access to perform asynchronous indexing。(已查文档确认)
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "Enable IAM User Permissions",
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::<ACCOUNT_ID>:root"},
"Action": "kms:*",
"Resource": "*"
},
{
"Sid": "Allow S3 Vectors indexing service",
"Effect": "Allow",
"Principal": {
"Service": "indexing.s3vectors.amazonaws.com"
},
"Action": "kms:Decrypt",
"Resource": "*",
"Condition": {
"StringEquals": {
"aws:SourceAccount": "<ACCOUNT_ID>"
}
}
}
]
}
# 保存 policy 到文件后应用
aws kms put-key-policy \
--key-id $KEY_ID \
--policy-name default \
--policy file://kms-policy.json \
--region us-east-1
创建 KMS 加密的索引:
aws s3vectors create-index \
--vector-bucket-name s3v-ga-demo \
--index-name idx-kms \
--data-type float32 \
--dimension 1024 \
--distance-metric cosine \
--encryption-configuration "{
\"sseType\": \"aws:kms\",
\"kmsKeyArn\": \"arn:aws:kms:us-east-1:<ACCOUNT_ID>:key/$KEY_ID\"
}" \
--region us-east-1
KMS key 必须使用完整 ARN
S3 Vectors 不支持 Key ID 或 Key Alias,必须使用完整的 KMS Key ARN。(已查文档确认)
验证两个索引的加密配置差异:
# 默认加密(SSE-S3)
aws s3vectors get-index \
--vector-bucket-name s3v-ga-demo \
--index-name idx-basic \
--region us-east-1 \
--query 'index.encryptionConfiguration'
# 输出: {"sseType": "AES256"}
# Per-index KMS 加密
aws s3vectors get-index \
--vector-bucket-name s3v-ga-demo \
--index-name idx-kms \
--region us-east-1 \
--query 'index.encryptionConfiguration'
# 输出: {"sseType": "aws:kms", "kmsKeyArn": "arn:aws:kms:..."}
Step 3: 资源标签(GA 新功能)¶
GA 版本支持为 vector bucket 和 index 添加标签,用于成本归因和基于属性的访问控制(ABAC)。
# 给 bucket 打标签
aws s3vectors tag-resource \
--resource-arn arn:aws:s3vectors:us-east-1:<ACCOUNT_ID>:bucket/s3v-ga-demo \
--tags '{"project": "s3v-ga-lab", "environment": "test"}' \
--region us-east-1
# 给 index 打标签
aws s3vectors tag-resource \
--resource-arn arn:aws:s3vectors:us-east-1:<ACCOUNT_ID>:bucket/s3v-ga-demo/index/idx-basic \
--tags '{"project": "s3v-ga-lab", "index-type": "basic"}' \
--region us-east-1
# 验证标签
aws s3vectors list-tags-for-resource \
--resource-arn arn:aws:s3vectors:us-east-1:<ACCOUNT_ID>:bucket/s3v-ga-demo \
--region us-east-1
# 输出: {"tags": {"environment": "test", "project": "s3v-ga-lab"}}
Step 4: 批量写入 5000 向量¶
为了测试 GA 版本的 Top-K 100 和查询性能,我们先批量写入 5000 个 1024 维向量:
import boto3, random, math, time
s3v = boto3.client("s3vectors", region_name="us-east-1")
def gen_vector(dim, seed):
"""生成归一化的随机向量"""
random.seed(seed)
v = [random.gauss(0, 1) for _ in range(dim)]
norm = math.sqrt(sum(x*x for x in v))
return [round(x/norm, 8) for x in v]
# 10 批 × 500 向量 = 5000 向量
for batch in range(10):
vectors = []
for i in range(500):
idx = batch * 500 + i
vectors.append({
"key": f"vec-{idx:05d}",
"data": {"float32": gen_vector(1024, seed=idx)},
"metadata": {
"batch": batch,
"idx": idx,
"category": f"cat-{idx % 10}"
}
})
t0 = time.time()
s3v.put_vectors(
vectorBucketName="s3v-ga-demo",
indexName="idx-basic",
vectors=vectors
)
print(f"Batch {batch}: {(time.time()-t0)*1000:.0f}ms")
实测写入结果:
| 批次 | 向量数 | 耗时 |
|---|---|---|
| Batch 0(冷启动) | 500 | 3335ms |
| Batch 1-9(稳定态) | 500 | 1483-1744ms |
| 总计 | 5000 | 20.83s |
| 有效吞吐 | ~240 vectors/s |
关于 1,000 TPS 的理解
官方的 "1,000 vectors per second" 指的是 streaming single-vector updates(每次 PUT 1 个向量,1000 次/秒)。批量写入 500 向量/请求时,受限于每次请求的网络和处理时间,实际吞吐约 240 vectors/s。两种模式面向不同场景:实时流式更新 vs 批量导入。(已查文档确认:"Combined PutVectors and DeleteVectors requests per second per vector index: Up to 1,000")
Step 5: Top-K 100 查询测试(GA 新能力)¶
Preview 版本 Top-K 最大为 30,GA 提升到 100。我们测试不同 Top-K 值对延迟的影响:
query_vec = gen_vector(1024, seed=9999)
for k in [5, 10, 30, 50, 100]:
latencies = []
for _ in range(10):
t0 = time.time()
resp = s3v.query_vectors(
vectorBucketName="s3v-ga-demo",
indexName="idx-basic",
queryVector={"float32": query_vec},
topK=k,
returnMetadata=True,
returnDistance=True
)
latencies.append((time.time() - t0) * 1000)
p50 = sorted(latencies)[4]
print(f"Top-K={k:3d}: p50={p50:.0f}ms, returned={len(resp['vectors'])}")
测试结果¶
Top-K 延迟对比(10 次采样, 5000 向量, 1024 维, cosine)¶
| Top-K | 平均延迟 | P50 | P90 | 最小 | 最大 | 返回数 |
|---|---|---|---|---|---|---|
| 5 | 394ms | 344ms | 517ms | 271ms | 567ms | 5 |
| 10 | 290ms | 275ms | 320ms | 270ms | 323ms | 10 |
| 30 | 323ms | 278ms | 450ms | 269ms | 553ms | 30 |
| 50 | 279ms | 274ms | 281ms | 270ms | 322ms | 50 |
| 100 | 277ms | 277ms | 281ms | 271ms | 291ms | 100 |
关键发现:Top-K 大小对查询延迟几乎没有影响。 从 Top-K=5 到 Top-K=100,P50 延迟稳定在 275ms 左右。这意味着你可以放心使用 Top-K=100 获取更多上下文,而不用担心性能惩罚。
冷查询 vs 热查询延迟¶
| 状态 | 查询延迟 | 说明 |
|---|---|---|
| 冷查询(90s 空闲后) | 1044ms | 仍在 sub-second 范围(勉强) |
| 热查询(连续查询) | 274ms (avg) | 非常稳定,标准差 < 3ms |
| 冷热差距 | ~4x | 冷启动惩罚明显 |
GA vs Preview 延迟对比¶
| 指标 | Preview 实测 | GA 实测 | 变化 |
|---|---|---|---|
| 热查询平均 | 305ms | 274ms | -10% ↓ |
| 热查询最小 | 267ms | 269ms | 基本持平 |
| 冷启动首查 | 371-391ms* | 1044ms | 不同条件 |
| Top-K 上限 | 30 | 100 | 3.3x ↑ |
*Preview 的"冷启动"是新建索引后立即查询,GA 的冷启动是 90s 空闲后,条件不完全一致。
关于 ~100ms 延迟
官方声称频繁查询可达 ~100ms。我们实测热查询稳定在 ~274ms,未能复现 100ms。这可能与查询频率有关 —— 我们的测试是连续 10 次查询后即停止,而 "频繁查询" 可能指持续高频(如每秒数次)的场景。对于偶发查询场景,274ms 的热查询延迟已经非常实用。
元数据边界测试¶
| 测试 | 结果 | 错误信息 |
|---|---|---|
| 50 个 metadata keys | ✅ 成功 | — |
| 51 个 metadata keys | ❌ 拒绝 | "Metadata object must have at most 50 keys" |
| 10 个 non-filterable keys | ✅ 成功 | — |
| 11 个 non-filterable keys | ❌ 拒绝 | "must have length between 1 and 10, inclusive" |
Per-Index KMS 加密验证¶
| 索引 | 加密类型 | KMS Key | 写入 | 查询 |
|---|---|---|---|---|
| idx-basic | SSE-S3 (AES256) | — | ✅ | ✅ |
| idx-kms | SSE-KMS | 自定义 CMK | ✅ | ✅ 394ms |
两个索引的读写行为完全一致,KMS 加密对使用体验透明。
踩坑记录¶
注意
-
KMS key policy 必须授权 S3 Vectors 服务主体:创建 per-index KMS 加密的索引前,必须先更新 KMS key policy,授权
indexing.s3vectors.amazonaws.com的kms:Decrypt权限。否则创建索引会直接报AccessDeniedException。(已查文档确认) -
KMS key 只能用 ARN,不支持 Key ID 或 Alias:
--encryption-configuration中的kmsKeyArn必须是完整的 Key ARN 格式。(已查文档确认) -
"1,000 TPS" 是请求级别,不是向量级别:官方限制 "Combined PutVectors and DeleteVectors requests per second per vector index: Up to 1,000" 指的是 API 请求数,每个请求最多包含 500 个向量。批量写入时的实际向量吞吐取决于 batch size 和网络延迟。(已查文档确认)
-
加密和维度仍然创建后不可改:与 Preview 一致,encryption type、dimension、distance metric、non-filterable metadata keys 创建后均不可修改。GA 没有改变这一限制。(已查文档确认)
费用明细¶
| 资源 | 单价 | 用量 | 费用 |
|---|---|---|---|
| S3 Vectors 存储 | 按量计费 | 5000 向量 × 1024 维 | < $0.01 |
| S3 Vectors 查询 | 按量计费 | ~100 次查询 | < $0.01 |
| KMS Key | $1/月 | 按比例(测试后立即删除) | < $0.05 |
| 合计 | < $0.10 |
定价亮点
GA 版本的定价有阶梯优惠:索引超过 10 万向量后,每 TB 查询费用更低。对于大规模向量存储场景,成本优势更明显。
清理资源¶
# 1. 删除所有 vector index
for idx in idx-basic idx-kms idx-nfm10; do
aws s3vectors delete-index \
--vector-bucket-name s3v-ga-demo \
--index-name $idx \
--region us-east-1
done
# 2. 删除 vector bucket(需先删除所有 index)
aws s3vectors delete-vector-bucket \
--vector-bucket-name s3v-ga-demo \
--region us-east-1
# 3. 禁用并计划删除 KMS key(最短等待 7 天)
aws kms schedule-key-deletion \
--key-id <KEY_ID> \
--pending-window-in-days 7 \
--region us-east-1
# 4. 验证清理完成
aws s3vectors list-vector-buckets --region us-east-1
务必清理
Lab 完成后请执行清理步骤。虽然 S3 Vectors 费用极低,但 KMS key 每月 $1,不删除会持续计费。
结论与建议¶
GA 版本升级亮点总结¶
| 能力 | 对生产环境的意义 |
|---|---|
| 20 亿向量/索引 | 绝大多数场景无需分片,架构大幅简化 |
| Top-K 100 | RAG 场景可获取更多上下文,且无延迟惩罚 |
| Per-Index KMS 加密 | 多租户隔离的关键能力,满足合规要求 |
| 资源标签 | 成本归因 + ABAC 访问控制 |
| CloudFormation + PrivateLink | IaC 部署 + 私有网络连接,生产级就绪 |
| 14 Regions | 全球覆盖显著扩大 |
实测建议¶
- 放心使用 Top-K=100:实测证明 Top-K 大小对延迟几乎无影响,RAG 场景建议直接用 100 获取更丰富的上下文
- 多租户场景用 Per-Index KMS:每个租户一个索引 + 独立 KMS key,数据隔离和密钥管理都能满足
- 注意冷启动延迟:不频繁查询的索引首次查询约 1 秒,之后稳定在 ~274ms。对延迟敏感的场景可考虑定期 warmup 查询
- 批量导入用大 batch:写入吞吐受限于请求次数(1,000 TPS),用 500 向量/batch 比逐条写入效率高得多
与 Preview 文章的互补关系¶
| 内容 | Preview 篇 | GA 篇(本文) |
|---|---|---|
| 基础 CRUD | ✅ 详细 | 简要 |
| Cosine vs Euclidean | ✅ 对比 | — |
| 元数据过滤语法 | ✅ 详细 | — |
| 维度边界 1-4096 | ✅ 测试 | — |
| Per-Index KMS 加密 | — | ✅ 新增 |
| Top-K 100 | — | ✅ 新增 |
| 资源标签 | — | ✅ 新增 |
| 写入吞吐测试 | — | ✅ 新增 |
| 冷/热延迟对比 | 部分 | ✅ 完整 |