跳到内容
SIAX.io

迁移指南 · 来自 AWS S3

从 AWS S3 迁移到 SIAX 对象存储

S3 API 已经成为行业标准,这对任何想离开它的人来说都是好消息。我们的对象存储讲着同样的协议,采用 signature v4,这意味着你的 SDK、工具和库可以原样工作,你只换 endpoint 和密钥,不换代码。

迁移的原因通常是流量。存储在哪里都便宜;在 AWS,花钱的是出站数据,而任何向最终用户提供文件的服务,其出口流量账单都会很快超过存储账单。我们的对象存储每月每 100 GB 25 克朗,所有数据都在欧盟境内。

复制本身是个已解决的问题,rclone 就能搞定,没什么需要发明的。工作在其他地方:IAM 角色没有对应物,必须用密钥对和存储桶策略来替代,而代码中每一处生成预签名 URL 的地方都必须重写,因为签名绑定在 endpoint 和区域。为这一点做好规划,迁移就波澜不惊。不做规划,你会在切换当天才发觉。

所需时间

对一个几百 GB、对象数量正常的存储桶来说,一个下午。复制很少是问题所在,费时间的是访问和预签名流程的重写,通常取决于代码中有多少处在与 S3 打交道,需要一到三个开发日。Glacier 中的已归档对象还会增加数天的等待时间。

停机时间

如果在重叠期间做双写,则零停机:两个目标都写,从 S3 读,等增量同步追上后再切换读取。不做双写的话,在最后同步期间需要一个只读模式下的写入窗口,从几分钟到一小时,取决于批量复制以来发生了多少变化。CDN 的切换有自己的尾巴,由 TTL 决定。

01

操作步骤

  1. 1

    按对象数量(而不只是体积)盘点存储桶

    用 aws s3 ls --summarize 或 Storage Lens 读取每个存储桶的大小、对象数量、存储类别和版本化状态。对象数量比 TB 数更能影响耗时:一千万个小文件比五 TB 的大块花费更长。同时记录是谁在向每个存储桶写入,这份清单决定了切换必须是什么样子。

  2. 2

    在我们这里创建存储桶和密钥,并配置 rclone

    建立对应的存储桶,每个应用一个密钥对,而不是所有东西共享一把。针对我们的 endpoint 配置一个类型为 s3 的 rclone remote,并按我们的说明设置区域和寻址风格。先用少量文件测试,确认 content-type 和其他元数据能带过来,然后再放开全量复制。

  3. 3

    运行批量复制

    rclone copy s3:bucket siax:bucket --transfers 32 --checkers 64 --fast-list 是一个合理的起点;把并行度调高,直到吞吐量趋于平稳。最好从与存储桶同一 AWS 区域内的实例运行,以缩短时间,反正你都要支付 AWS 的出网费用。位于 Glacier 或 Deep Archive 中的对象必须先恢复,这需要数小时到数天。

  4. 4

    在信任这份复制之前先验证

    rclone check --one-way 会逐个对象比较大小和校验和。还要比较源与目标之间的总对象数,并抽查应用实际读取的 content-type、cache-control 等响应头。一份字节看起来正确、但丢失了元数据的复制,会产生只在浏览器里才暴露的错误。

  5. 5

    重写访问,这才是真正的活

    我们这里没有 IAM:角色、实例 profile、AssumeRole 和基于条件的策略,都由密钥对和存储桶策略替代。逐一过一遍每一处生成预签名 URL 的地方,重定向 endpoint、区域和签名配置,因为签名与这三者都绑定。更新 CORS 规则,并从浏览器测试上传,而不只是从服务器测试。

  6. 6

    双写切换并保留退路

    让应用在重叠期间向两个目标写入,并继续从 S3 读取,直到增量同步追上进度。然后切换读取,运行最后一次 rclone sync,重定向 CDN 或 CloudFront 分发。为存储桶设置一份独立的备份(19 克朗/100 GB),两个系统之间的复制不等于备份,并把 S3 存储桶至少保留 30 天只读,然后才设置删除的 lifecycle 规则。

02

真正棘手的地方

  • IAM 不会迁移,而且它比听起来更费事。EC2 和 ECS 实例上的角色、跨账户的 AssumeRole、基于标签的条件,以及来自 CI 的 OIDC 联合,都由静态密钥对替代。以前从不需要处理密钥的应用现在必须处理了,这会波及部署流程,而不只是代码。
  • 预签名 URL 必须到处重新生成。签名绑定在 endpoint、区域和密钥上,因此后端、批处理作业和任何移动客户端都必须重新指向并测试。已经发出、有效期很长的链接会在切换那一刻失效,如果你会通过邮件发送下载链接,请为此规划。
  • Glacier 和 Deep Archive 中的对象无法直接复制。必须先恢复,这要花钱,而且根据检索层级需要几小时到几天。对于归档繁重的账户,这一步往往支配着整个时间表。
  • 离开 AWS 要付出网费用:在约 100 GB/月的免费额度以上,大约每 GB 0.09 USD,也就是说 5 TB 大约 450 USD,一次性成本。自 2024 年起,AWS 对完全离开平台的客户提供免出网费,但需要向支持申请,并且不适用于部分迁移。在预算之前先核对条款。
  • 标准工具复制的是每个对象的当前版本,不带版本历史、不带对象 ACL、不带 lifecycle 规则,也不带复制设置。触发 Lambda 的 S3 事件通知没有直接对应物,必须在应用侧重建。如果出于监管原因你有 compliance 模式下的 Object Lock,请在规划迁移之前先与我们核实,而不是之后。
03

成本示例

S3 Standard 上每月存储 500 GB、出站流量 200 GB:存储约 0.023 USD/GB,流量在免费额度以上约 0.09 USD/GB,再加上请求成本,大约每月 300-350 克朗。AWS 价格因地区而异且不断变化,请根据你自己的账单计算。同样的 500 GB 在我们这里要 125 克朗/月(每 100 GB 25 克朗)。在此之上还有从 S3 读出的数据的一次性成本,500 GB 约 45 USD,除非你有资格享受免出网费。按这个画像,迁移大概两三个月就能回本。如果你存储量大而流量小,回本更慢、收益更小,值得在决定之前算一算。

04

常见问题

我们必须更换 SDK 或重写代码吗?
不必。API 是兼容 S3 的,采用 signature v4,因此同一个 SDK 就能用,你只换 endpoint、区域,可能还有寻址风格。请单独测试 multipart 上传和 CORS,差异往往出现在那里。
版本历史会一起迁移吗?
不会。rclone 和 aws s3 sync 复制的是每个对象的当前版本。如果需要保留历史,那是另一个项目:要么把每个版本显式地作为独立对象复制,要么把 S3 存储桶保留为只读档案。
把数据从 AWS 迁出来要多少钱?
在免费额度以上大约每 GB 0.09 USD,也就是每 TB 大约 90 USD。自 2024 年起,AWS 依据欧盟数据法案,对完全离开平台的客户提供免出网费,但需要向支持申请并获批。请把成本纳入预算,并把免费路径视为获批后的红利。
我们能在 S3 上保留一些存储桶吗?
可以。很多人会先把出网成本差异最大的流量重存储桶迁走,让归档数据留在 Glacier 里直到反正要被清除。对头一年来说,混合方案往往是正确答案。
S3 事件通知和 Lambda 触发器怎么办?
它们需要重建。通常的模式是,写对象的应用也把任务放进队列,而不是依赖存储系统生成事件。这会变得更显式、更容易调试,但这是一次重写,需要放进时间表。
你们有 ISO 27001 或 SOC 2 吗?
没有,我们既没有 ISO 27001、SOC 2,也没有 PCI-DSS。我们能展示 GDPR 合规、数据处理协议,以及所有数据都存储在欧盟境内,而且一路开源到底,这样你能审计实现。如果你的采购流程有硬性认证要求,单就这一点而言 AWS 比我们更合适,直说更诚实。