跨 AWS 账号同步 S3 存量与新增对象
验证:未记录
- 适用版本
- 未记录
- 验证范围
- 尚未登记验证记录。
本文缩写(英文全称与中文含义)
| 缩写 | 英文全称/名称 | 中文含义 |
|---|---|---|
| ACL | Access Control List | 访问控制列表 |
| AES256 | Advanced Encryption Standard, 256-bit key | 使用 256 位密钥的高级加密标准 |
| ARN | Amazon Resource Name | AWS 资源名称,用于唯一标识资源 |
| AWS | Amazon Web Services | 亚马逊云服务 |
| HTTP | Hypertext Transfer Protocol | 超文本传输协议 |
| IAM | Identity and Access Management | 身份与访问管理 |
| ID | Identifier | 标识符 |
| JSON | JavaScript Object Notation | 一种结构化数据格式 |
| KMS | Key Management Service | 密钥管理服务 |
| S3 | Simple Storage Service | AWS 对象存储服务 |
| SCP | Service Control Policy | AWS Organizations 服务控制策略 |
| SLA | Service Level Agreement | 服务等级协议 |
| TLS | Transport Layer Security | 传输层安全协议 |
| URL | Uniform Resource Locator | 统一资源定位符,通常指访问地址 |
| VPC | Virtual Private Cloud | 虚拟私有云网络 |
1. 需求与推荐方案#
需求:将 AWS Account A 中 source bucket A1 的存量对象,以及启用方案后持续写入的新对象,复制到 AWS Account B 中 destination bucket B2。
推荐使用两项原生能力组合:
新增对象:
S3 Replication
持续、异步复制启用规则后产生的新 object version
存量对象:
S3 Batch Replication
一次性回填启用规则前已经存在的 object version不要只运行一次 aws s3 sync:它适合按当前 key 对比后复制文件,但不是持续复制服务,也不能完整保留 version、replication status、Object Lock retention、tag 和 delete marker 等 S3 语义。
Account A Account B
producer -> A1 source bucket B2 destination bucket
| ^
| S3 Replication: new versions |
+------------------------------------------+
| |
| S3 Batch Replication: existing versions |
+------------------------------------------+
replication IAM role in Account A
destination bucket policy trusts that roleS3 Replication 是异步复制,不是事务型实时双写。一般会在较短时间内完成,但没有启用 S3 Replication Time Control(S3 RTC)时,不应承诺固定延迟。需要延迟 SLA 时可启用 S3 RTC,它会增加费用,并提供 99.99% 的新对象在 15 分钟内完成复制的 SLA。
2. 实施顺序#
为避免配置期间产生数据缺口,按以下顺序操作:
- 在 Account B 准备
B2,启用 Versioning、Block Public Access 和 Bucket owner enforced。 - 在 Account A 创建给 S3 使用的 replication IAM role。
- 在
B2bucket policy 中授权该 replication role 写入副本。 - 如果使用 SSE-KMS,配置 source/destination KMS key policy。
- 确认
A1已启用 Versioning,然后先启用持续 replication rule。 - 创建 S3 Batch Replication job,回填规则启用前的存量对象。
- 监控持续复制和 batch job,抽样校验对象、版本、加密和 tag。
先启用持续复制,再启动存量回填。这样在 batch job 扫描和运行期间新写入的对象已由持续复制规则接管。
3. 前置条件#
示例变量:
SOURCE_ACCOUNT_ID=111111111111
DESTINATION_ACCOUNT_ID=222222222222
SOURCE_BUCKET=account-a-bucket-a1
DESTINATION_BUCKET=account-b-bucket-b2
SOURCE_REGION=ap-east-1
DESTINATION_REGION=ap-southeast-1
REPLICATION_ROLE_NAME=s3-a1-to-b2-replication必须满足:
A1 和 B2 都启用 S3 Versioning
B2 已存在,bucket name 和 Region 已确认
Account A 有权限创建 IAM role 和修改 A1 replication configuration
Account B 有权限修改 B2 bucket policy
两边的 SCP、permissions boundary、VPC endpoint policy 没有显式拒绝相关操作
使用 SSE-KMS 时,两边都使用 customer managed KMS key,并配置跨账号 key policy迁移前检查 A1 当前配置#
下面的命令都是只读检查,用来建立 A1 的迁移基线。建议使用 Account A 的实际操作 profile 和 bucket Region;命令返回 AccessDenied 只说明当前身份没有读取权限,不能据此判断该功能没有配置。
aws s3api get-bucket-versioning --bucket A1
aws s3api get-bucket-encryption --bucket A1
aws s3api get-bucket-ownership-controls --bucket A1
aws s3api get-object-lock-configuration --bucket A1
aws s3api get-bucket-lifecycle-configuration --bucket A1
aws s3api get-bucket-replication --bucket A1
aws s3api get-bucket-policy --bucket A1| 命令 | 检查内容 | 重点关注 |
|---|---|---|
get-bucket-versioning |
bucket 的 Versioning 状态 | {} 通常表示从未启用、当前为 Disabled;Enabled 可以配置 replication;Suspended 表示曾启用但当前暂停,必须恢复为 Enabled |
get-bucket-encryption |
新对象默认使用的 server-side encryption | AES256 表示 SSE-S3;aws:kms 或 aws:kms:dsse 表示 KMS,需要记录 KMS key ARN,并配置跨账号 key policy |
get-bucket-ownership-controls |
新对象的 ownership 和 ACL 模式 | 推荐 BucketOwnerEnforced;如果没有 ownership controls 或仍使用 ACL,需要检查 source/destination object owner 和 ACL 依赖 |
get-object-lock-configuration |
bucket 是否启用 Object Lock,以及默认 retention | 若为 Enabled,B2 也必须按要求启用 Object Lock,并复制 retention/legal hold;未配置通常返回 ObjectLockConfigurationNotFoundError |
get-bucket-lifecycle-configuration |
Lifecycle filter、transition、expiration 和 noncurrent version 处理 | 开启 Versioning 后要特别检查 noncurrent version expiration;B2 不会自动继承 A1 的 Lifecycle,需要单独配置 |
get-bucket-replication |
A1 是否已有 replication configuration |
检查 role、rule priority、filter、destination、delete marker、KMS、metrics 和 RTC,避免新规则冲突或重复复制;未配置通常返回 ReplicationConfigurationNotFoundError |
get-bucket-policy |
bucket resource policy | 查找针对 principal、Organization、VPC endpoint、TLS、KMS 或加密 header 的 explicit deny;未配置通常返回 NoSuchBucketPolicy |
建议保存这些命令的 JSON 输出作为变更前记录。除 Versioning 外,最容易阻塞跨账号复制的是 SSE-KMS key policy、已有 bucket policy 的 explicit deny、Object Lock 要求和现有 replication rule。
启用 Versioning:
aws s3api put-bucket-versioning --profile account-a --region ap-east-1 --bucket account-a-bucket-a1 --versioning-configuration Status=Enabled
aws s3api put-bucket-versioning --profile account-b --region ap-southeast-1 --bucket account-b-bucket-b2 --versioning-configuration Status=EnabledA1 从 Disabled 开启 Versioning 的影响#
开启 Versioning 不会重写或删除现有对象:
existing objects:
remain as null versions
new PUT or overwrite:
creates a new version ID
previous current/null version becomes noncurrent
DELETE without version ID:
creates a delete marker
previous data version remains stored首次开启后,关键 PUT/DELETE 或 replication rollout 前建议等待约 15 分钟让配置传播。Versioning 开启后不能恢复为初始 Unversioned,只能改成 Suspended。
普通应用的 PutObject/GetObject/HeadObject/ListObjectsV2 和 presigned URL 通常不需要修改;不指定 versionId 时仍操作 current version。需要检查:
permanent delete/cleanup jobs:
must handle object versions and delete markers
event consumers:
may need versionId for idempotency
cost:
configure Lifecycle for noncurrent versions and incomplete multipart uploads持续 replication rule 只自动处理规则生效后的新 versions;现有 null/current objects 使用 Batch Replication 回填。开启前已经永久删除或被覆盖的历史数据无法恢复。
推荐让 destination bucket 使用 Bucket owner enforced。Account B 会拥有复制到 B2 的对象,并且不再依赖 ACL:
aws s3api put-bucket-ownership-controls --profile account-b --region ap-southeast-1 --bucket account-b-bucket-b2 --ownership-controls 'Rules=[{ObjectOwnership=BucketOwnerEnforced}]'为什么要确认 tags、metadata、Object Lock retention 和 legal hold#
这些属性不一定改变 object body,但可能改变目标端的权限、生命周期、HTTP 行为和删除能力。迁移前询问它们,是为了确认 B2 要成为功能等价副本,还是只需要保存对象内容。
| 属性 | 含义 | 为什么需要确认 | 推荐答案 |
|---|---|---|---|
| Object tags | object 上独立维护的 key-value 标签 | 可能被 Lifecycle、IAM condition、成本分类和自动化任务使用;遗漏后,B2 的过期、转存或访问行为可能改变 |
默认复制,除非明确确认目标端不依赖 tags |
| Object metadata | 随 object version 保存的属性,包括 Content-Type、Cache-Control、Content-Disposition 和自定义 x-amz-meta-* |
应用下载行为、浏览器缓存、文件类型和业务处理可能依赖 metadata;只复制 body 可能导致对象在目标端不可正常使用 | 默认保留业务 metadata,同时允许 destination encryption、storage class 等目标属性按设计变化 |
| Object Lock retention | 对一个 object version 设置不可删除/覆盖的截止时间 | 决定副本在 Account B 中何时可以删除,涉及合规、审计和存储成本 | source 使用 Object Lock 时必须保留并让合规负责人确认;未使用时不需要启用 |
| Legal hold | 对一个 object version 设置无固定到期时间的法律保留开关 | ON 状态会一直阻止删除,直到有权限的人员显式解除;常用于诉讼、调查或证据保全 |
source 存在 legal hold 时必须保留,不能把迁移当作绕过保留的方法 |
严格来说,业务/HTTP metadata 在原生 S3 Replication 中通常会随 object version 复制,不是一个常规的“复制/不复制”开关。询问 metadata 的目的主要是确定验收标准,并检查目标端更换 KMS key、storage class 或下载方式后是否仍兼容。Tags 则更直接涉及额外权限以及目标端 Lifecycle/IAM 行为,因此必须明确确认。
Tags#
Tags 和 metadata 不相同。Tags 可在不复制 object body 的情况下单独修改,通常用于:
Lifecycle filter:
tag=archive -> transition to Glacier
IAM condition:
s3:ExistingObjectTag/classification=confidential
operations:
backup=true
retention-class=finance-7y
owner=team-aS3 Replication 可以复制 tags,但 replication role 需要读取 source tags,并允许在 destination 执行 s3:ReplicateTags。本文策略中的 s3:GetObjectVersionTagging 和 s3:ReplicateTags 就是为此准备的。
如果不复制 tags,object body 可能仍然复制成功,但 B2 上基于 tags 的 Lifecycle、IAM 或自动化行为会与 A1 不一致。因此默认答案应为“复制 tags”;只有在 B2 明确不继承这些控制时才选择不复制,并进行单独验证。
检查一个 source object 的 tags:
aws s3api get-object-tagging --profile account-a --bucket account-a-bucket-a1 --key path/to/object --version-id SOURCE-VERSION-IDMetadata#
Metadata 分为两类:
business/HTTP metadata:
Content-Type
Cache-Control
Content-Disposition
Content-Encoding
x-amz-meta-* custom metadata
storage/security metadata:
storage class
encryption algorithm and KMS key
replication statusS3 Replication 通常会让 replica 保留 source object version 的业务/HTTP metadata。Destination storage class、KMS key 和 replication status 可以按 replication rule 使用目标端配置,不要求和 source 完全相同。
S3 metadata 不能直接原地修改。需要修改时,是应用程序、运维脚本、管理员或 S3 Console 主动调用 CopyObject,把对象复制回同一个 key,并通过 MetadataDirective=REPLACE 替换 metadata。S3 Replication 不会为了同步而在 A1 上调用 CopyObject,也不会主动修改 source object。
application / operator calls CopyObject on A1
-> A1 creates a new object version for the same key
-> continuous replication detects the new version
-> S3 asynchronously creates its replica in B2例如修改一个对象的 metadata:
aws s3api copy-object --profile account-a --bucket account-a-bucket-a1 --copy-source account-a-bucket-a1/path/to/object --key path/to/object --metadata-directive REPLACE --content-type application/json --metadata owner=team-a,classification=internalREPLACE 会使用请求中提供的新 metadata 取代原 metadata,因此必须重新提供仍需保留的 Content-Type、Cache-Control 和自定义 x-amz-meta-*,否则遗漏字段会丢失。没有修改 metadata 的业务需求时,不要为了 replication 主动执行 CopyObject。
如果 A1 当前是 Disabled,开启 Versioning 后,原有对象通常仍是 null version。随后对同一个 key 执行 CopyObject 会创建新的正式 version,原 null version 成为 noncurrent version;新 version 会在持续复制规则生效后进入 replication。存量对象不需要修改 metadata 时,直接使用 Batch Replication 回填即可。
因此需要确认应用是否会频繁修改 metadata,以及这些变更是否必须在 B2 可见。频繁的同 key CopyObject 会增加 version 数量、复制请求和存储成本。
检查一个对象的 metadata:
aws s3api head-object --profile account-a --bucket account-a-bucket-a1 --key path/to/object --version-id SOURCE-VERSION-IDObject Lock retention#
Object Lock 是 WORM(write once, read many)保护,作用对象是具体的 object version,而不是整个 key 的抽象名称。
Retention 会设置 RetainUntilDate:
GOVERNANCE:
默认不能提前删除
具有 s3:BypassGovernanceRetention 的受控角色可以显式绕过
COMPLIANCE:
retention 到期前不能删除
包括 root user 在内也不能提前缩短或绕过例如一个 version 的 retention 截止到 2030-12-31,即使业务已经不再需要该对象,在此日期前也不能删除该 version。Retention 到期后只是“允许删除”,不会自动删除;是否删除仍由 Lifecycle 或显式 DELETE 决定。
Legal hold#
Legal hold 只有 ON/OFF,没有自动到期时间,并且独立于 retention:
retention 已到期 + legal hold ON:
仍然不能删除
retention 未到期 + legal hold OFF:
仍然不能删除
retention 已到期 + legal hold OFF:
可以按 IAM 和 Lifecycle 规则删除Legal hold 常用于诉讼、监管调查、安全事件证据或审计资料。它必须由有权限的人员显式设为 OFF,迁移过程不能擅自解除。
Object Lock 对复制的影响#
如果 A1 启用了 Object Lock,则 B2 也必须启用 Object Lock,replication role 需要读取 source retention 和 legal hold。Replica 应保留这些保护状态,否则目标 bucket 不能作为合规副本。
检查 bucket 是否启用 Object Lock:
aws s3api get-object-lock-configuration --profile account-a --bucket account-a-bucket-a1检查一个 object version:
aws s3api get-object-retention --profile account-a --bucket account-a-bucket-a1 --key path/to/object --version-id SOURCE-VERSION-ID
aws s3api get-object-legal-hold --profile account-a --bucket account-a-bucket-a1 --key path/to/object --version-id SOURCE-VERSION-IDObject Lock 依赖 Versioning。若 A1 当前确实是从未启用过 Versioning 的 Disabled 状态,正常情况下它不会已经启用 Object Lock,也不会存在 retention 或 legal hold;仍建议运行上面的 bucket-level 命令确认,并区分“未配置”与调用者没有读取权限导致的 AccessDenied。
4. Account A Replication Role#
创建 trust policy replication-role-trust.json,只允许 S3 service assume 该 role:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "s3.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}aws iam create-role --profile account-a --role-name s3-a1-to-b2-replication --assume-role-policy-document file://replication-role-trust.json创建权限策略 replication-role-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "ReadSourceBucketConfiguration",
"Effect": "Allow",
"Action": [
"s3:GetReplicationConfiguration",
"s3:ListBucket"
],
"Resource": "arn:aws:s3:::account-a-bucket-a1"
},
{
"Sid": "ReadSourceObjectVersions",
"Effect": "Allow",
"Action": [
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl",
"s3:GetObjectVersionTagging",
"s3:GetObjectRetention",
"s3:GetObjectLegalHold"
],
"Resource": "arn:aws:s3:::account-a-bucket-a1/*"
},
{
"Sid": "WriteDestinationReplicas",
"Effect": "Allow",
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags"
],
"Resource": "arn:aws:s3:::account-b-bucket-b2/*"
}
]
}aws iam put-role-policy --profile account-a --role-name s3-a1-to-b2-replication --policy-name replicate-a1-to-b2 --policy-document file://replication-role-policy.json如果只同步某个 prefix,应同时缩小 replication rule 的 filter 和 IAM policy 的 object resource,例如 arn:aws:s3:::account-a-bucket-a1/data/*。
5. Account B Bucket Policy#
在 Account B 为 B2 添加 bucket policy。下面只展示 replication 相关 statement;如果 bucket 已有 policy,需要合并到现有 Statement,不能直接覆盖其他 guardrail:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowReplicationFromAccountA",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111111111111:role/s3-a1-to-b2-replication"
},
"Action": [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags"
],
"Resource": "arn:aws:s3:::account-b-bucket-b2/*"
}
]
}aws s3api put-bucket-policy --profile account-b --region ap-southeast-1 --bucket account-b-bucket-b2 --policy file://destination-bucket-policy.json如果 B2 policy 有 Deny 条件,例如只允许指定 aws:PrincipalAccount、VPC endpoint、AWS Organization 或加密方式,必须把 replication role 和 S3 replication 请求纳入条件设计。Allow 无法覆盖任何 explicit Deny。
6. 启用持续复制#
SSE-S3 或未指定 SSE-KMS#
创建 replication.json:
{
"Role": "arn:aws:iam::111111111111:role/s3-a1-to-b2-replication",
"Rules": [
{
"ID": "replicate-all-to-account-b",
"Priority": 1,
"Status": "Enabled",
"Filter": {
"Prefix": ""
},
"DeleteMarkerReplication": {
"Status": "Enabled"
},
"Destination": {
"Bucket": "arn:aws:s3:::account-b-bucket-b2"
}
}
]
}aws s3api put-bucket-replication --profile account-a --region ap-east-1 --bucket account-a-bucket-a1 --replication-configuration file://replication.json检查规则:
aws s3api get-bucket-replication --profile account-a --region ap-east-1 --bucket account-a-bucket-a1SSE-KMS#
如果 source object 使用 SSE-KMS,仅有 S3 和 IAM 权限不够。需要:
source KMS key:
replication role 可以 kms:Decrypt
destination KMS key:
replication role 可以 kms:Encrypt 和 kms:GenerateDataKey
replication rule:
启用 SseKmsEncryptedObjects
指定 destination ReplicaKmsKeyID应在 KMS key policy 中授权 replication role,并在 role policy 中加入相同的 KMS actions。不要使用 AWS managed key aws/s3 做跨账号授权,因为它的 key policy 不能由客户修改。
SSE-KMS replication rule 需要增加:
{
"SourceSelectionCriteria": {
"SseKmsEncryptedObjects": {
"Status": "Enabled"
}
},
"Destination": {
"Bucket": "arn:aws:s3:::account-b-bucket-b2",
"EncryptionConfiguration": {
"ReplicaKmsKeyID": "arn:aws:kms:ap-southeast-1:222222222222:key/DESTINATION-KEY-ID"
}
}
}如果 source bucket 同时存在 SSE-S3 和 SSE-KMS 对象,启用上述选项后两类对象都可进入同一规则;SSE-KMS 对象会使用指定的 destination KMS key 创建 replica。
7. 回填存量对象#
持续 replication rule 只自动处理规则生效后的新 object version,不会自动复制更早存在的对象。存量回填使用 S3 Batch Replication,不要暂停生产写入。
最稳妥的操作路径是 Account A 的 S3 Console:
- 打开
A1的 Management > Replication rules。 - 确认上一节的持续复制规则状态为 Enabled。
- 选择该规则,然后选择 Replicate existing objects 或创建 Batch Replication job。
- 让 S3 生成 manifest,范围选择整个 bucket 或目标 prefix。
- 为 Batch Operations 选择单独的 job role;该 role 需要对 source object 执行
s3:InitiateReplication,并能读取 manifest、写 completion report。 - 设置 completion report bucket,先 Review manifest,再确认运行 job。
- 等待 job 完成,并检查 failed task 数量和 completion report。
Batch Operations job role 和第 4 节的持续 replication role 是两个不同角色:
continuous replication role:
trusted service = s3.amazonaws.com
reads source versions and writes destination replicas
Batch Operations job role:
trusted service = batchoperations.s3.amazonaws.com
calls s3:InitiateReplication for each source object in the manifestBatch Operations job role 的 trust policy 核心内容:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "batchoperations.s3.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}job role 的 operation permission:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "InitiateReplicationForSourceObjects",
"Effect": "Allow",
"Action": "s3:InitiateReplication",
"Resource": "arn:aws:s3:::account-a-bucket-a1/*"
}
]
}还需要根据实际 bucket 增加 manifest 的 s3:GetObject/s3:GetObjectVersion 和 report prefix 的 s3:PutObject。使用 S3 generated manifest 时,Console 创建 role 的流程会补充生成 manifest 所需的 bucket 权限;上线前仍要检查最终 policy 是否只覆盖 A1、manifest 和 report 的指定位置。
对于关键数据,建议先用一个小 prefix 建 job 验证策略、KMS 和 ownership,再执行全量 job。Batch Operations 会产生请求、manifest、inventory、report、KMS 和跨 Region data transfer 等费用,先估算对象数量,不要只看总容量。
“历史数据”的范围#
在执行前明确业务所说的“历史数据”:
| 范围 | 做法 |
|---|---|
| 每个 key 的当前版本 | Batch Replication manifest 只包含当前 version |
| 所有非当前版本 | manifest 必须包含对应 VersionId,并逐版本执行 replication |
| delete marker | Batch Replication 不用于回填历史 delete marker;需要单独评估目标端应呈现的删除状态 |
| 已删除且没有保留版本的对象 | S3 已无可复制数据,只能从其他备份恢复 |
如果要求 B2 完整重建 A1 的版本时间线,不能把“复制当前可见对象”当作完成。必须检查 manifest 是否包含所有需要的 version ID,并接受历史 delete marker 等限制。
8. 删除与一致性语义#
什么是 delete marker#
在启用 Versioning 的 bucket 中,对一个 key 执行不带 version-id 的普通 DeleteObject 时,S3 通常不会删除已有 object version,而是创建一个新的 delete marker,并让它成为该 key 的 current version。
Delete marker 只有 key 和自己的 version ID,没有 object body。它的作用是让不指定 version ID 的 GET/HEAD 看起来像对象已经不存在,通常返回 404 Not Found;此前的数据版本仍作为 noncurrent version 保存在 bucket 中。
before DELETE:
reports/a.csv version v2 <- current and visible
reports/a.csv version v1
after DELETE without version-id:
reports/a.csv delete marker d1 <- current
reports/a.csv version v2 <- data still exists
reports/a.csv version v1
GET reports/a.csv:
returns 404 because d1 is current
GET reports/a.csv?versionId=v2:
can still read v2 if the caller has permission如果显式删除 current delete marker 的 version ID,之前的数据版本可重新成为 current version,对象也会再次可见。这是 Versioning 能从普通误删中恢复对象的原因之一。
A1 当前为 Versioning Disabled 时还没有 delete marker 机制:普通 DELETE 会直接删除对象。启用 Versioning 后产生的删除才会创建 delete marker;启用前已经删除且没有其他备份的对象无法通过 replication 恢复。
检查某个 key 的版本和 delete marker:
aws s3api list-object-versions --profile account-a --bucket account-a-bucket-a1 --prefix path/to/object输出中的 Versions 是数据版本,DeleteMarkers 是删除标记;IsLatest=true 表示当前版本。
是否需要复制 delete marker#
DeleteMarkerReplication=Enabled 表示:持续复制规则生效后,A1 中普通 DELETE 创建的新 delete marker,也会异步复制到 B2。复制后,B2 上相同 key 的普通 GET/HEAD 也会返回不存在,但此前复制的数据版本仍然保留,除非被 B2 自己的 Lifecycle 或显式删除清理。
B2 用途 |
建议 | 原因 |
|---|---|---|
| 灾备副本、故障切换、迁移后接管 | 通常 Enabled | B2 的当前可见 key 集合需要尽量与 A1 一致,否则源端已删除对象在切换后会重新出现 |
| 分析副本,且查询应反映源端当前状态 | 通常 Enabled | 避免分析程序继续读取已从业务侧删除的 key |
| 隔离备份、审计归档、防源端误删 | 通常 Disabled | 源端误删不应自动隐藏目标对象;目标端使用独立 Lifecycle、Object Lock 或 retention 控制保留 |
| 法规要求删除必须传播 | Enabled,但先做合规确认 | delete marker 只隐藏当前对象,不等于物理删除所有历史版本,未必满足数据彻底删除要求 |
对本文的 A1 -> B2 需求,如果 B2 是迁移副本或可直接接管业务的灾备 bucket,推荐启用 delete marker replication。如果 B2 的核心目标是提供不受 Account A 误操作影响的独立恢复副本,则推荐禁用,并限制 Account A 对 B2 的删除权限。
以下行为不要混淆:
delete current key without version ID:
creates a delete marker
can be replicated when DeleteMarkerReplication is enabled
permanently delete a specific source version:
is not propagated as a permanent deletion of the corresponding replica
lifecycle expires source objects or versions:
do not assume destination lifecycle follows it
destination needs its own lifecycle policy额外限制:使用 tag-based filter 的 replication rule 不支持启用 delete marker replication。需要传播删除时,应使用整个 bucket 或 prefix-based filter,并在测试 prefix 中验证 create、overwrite、delete 和 restore 行为。
因此 replication 不是镜像文件系统,也不是双向同步。即使启用了 delete marker replication,显式永久删除某个 source version 也不会自动永久删除对应 replica;历史 delete marker 也不能依靠 Batch Replication 完整回填。不要在 B2 上配置反向规则复制回 A1,除非已经设计好 loop prevention、ownership、冲突和删除语义。
9. 验证与监控#
先写一个 canary object:
printf 'replication-check\n' > /tmp/replication-check.txt
aws s3api put-object --profile account-a --region ap-east-1 --bucket account-a-bucket-a1 --key replication-canary/replication-check.txt --body /tmp/replication-check.txt检查 source object 的 replication status:
aws s3api head-object --profile account-a --region ap-east-1 --bucket account-a-bucket-a1 --key replication-canary/replication-check.txt --query '{VersionId:VersionId,ReplicationStatus:ReplicationStatus}'常见状态:
PENDING 等待或正在复制
COMPLETED 已复制成功
FAILED 复制失败,需要检查权限、KMS、bucket policy 和 replication metrics
REPLICA 当前对象本身是 replica检查 destination:
aws s3api head-object --profile account-b --region ap-southeast-1 --bucket account-b-bucket-b2 --key replication-canary/replication-check.txt --query '{VersionId:VersionId,ReplicationStatus:ReplicationStatus,SSE:ServerSideEncryption,KMSKey:SSEKMSKeyId}'生产环境应启用 S3 replication metrics 和 EventBridge failure events,并关注:
OperationsFailedReplication
OperationsPendingReplication
BytesPendingReplication
ReplicationLatency
s3:Replication:OperationFailedReplication EventBridge event
Batch Operations job failed task count and completion report验证至少覆盖:
新对象可以自动复制
覆盖同一个 key 后,新 version 可以复制
普通 DELETE 的 delete marker 行为符合预期
对象 tag 已复制
SSE-KMS destination key 正确
Account B 对 replica 有读取和 lifecycle 管理权限
存量 batch job 的 manifest 数量、成功数、失败数可以对账10. 常见失败#
| 现象 | 优先检查 |
|---|---|
新对象一直 PENDING |
replication rule status、role trust policy、destination bucket policy |
FAILED 且对象是 SSE-KMS |
source key kms:Decrypt、destination key kms:Encrypt、key policy、key Region |
| 新对象成功但旧对象不存在 | 只配置了持续 replication,没有运行 Batch Replication |
| destination 拒绝写入 | bucket policy/SCP/VPC endpoint policy 中的 explicit deny |
| replica owner 不符合预期 | B2 是否为 Bucket owner enforced,是否仍依赖 ACL |
| tag 没有复制 | role 和 destination policy 是否允许 s3:ReplicateTags |
| 删除后两边结果不同 | delete marker 与指定 version 永久删除的语义不同 |
| batch job 大量失败 | completion report、manifest version ID、Batch Operations role、KMS policy |
11. 上线 Checklist#
[ ] A1/B2 Versioning 都是 Enabled
[ ] B2 Block Public Access 已启用
[ ] B2 Object Ownership 是 Bucket owner enforced
[ ] replication role trust 只允许 s3.amazonaws.com
[ ] role policy 只覆盖 A1 source 和 B2 destination
[ ] B2 bucket policy 精确授权 replication role
[ ] SSE-KMS 两边 key policy 和 role policy 已配置
[ ] 先启用持续 replication,再启动存量 Batch Replication
[ ] Batch manifest 明确是当前版本还是全部历史版本
[ ] completion report 有独立保存位置并完成失败项复核
[ ] canary 的 create/overwrite/delete/tag/encryption 已验证
[ ] replication metrics、EventBridge failure event 和告警已配置
[ ] B2 lifecycle、retention、Object Lock 需求已独立确认