跳转到内容
HexaTransfer
返回博客
云与存储

多云文件管理:避免厂商锁定

跨多家云服务商管理文件。避免厂商锁定、优化成本,并在平台间保持一致的访问体验。

多云文件管理意味着将数据存储在两个或更多服务商(比如 AWS S3 加 Cloudflare R2 加 Backblaze B2)之后,用一个统一抽象层将任何一个都视为给定文件的有效存储位置。实际收益是:对冲厂商故障风险、在合同续签时拥有谈判筹码,以及通过为每个工作负载选择合适的服务商将出口成本压近零。技术要素:以 S3 兼容 API 作为通用语言,rclone 或 MinIO Gateway 作为可移植客户端,记录每个对象所在服务商的元数据索引(Postgres 或 DynamoDB 兼容),以及通过 HashiCorp Vault 或 AWS Secrets Manager 进行 CI 可强制执行的凭证清单。

锁定实际代价几何

锁定很少是一张巨额账单——它是一百个小摩擦。一旦你的代码使用 aws s3 cp,硬编码 us-east-1,依赖 S3 Select,或依赖 DynamoDB 流,迁移到别处就意味着重写所有这些。出口费用是最显眼的税:AWS 前10TB的出口收每GB约0.63元。从 AWS 迁出50TB,仅带宽费约2.8万元,不算工程师时间。

不那么明显的:Glacier 保险库锁、S3 事件上的 Lambda 触发器、IAM Access Analyzer 等专有功能都会变成迁移项目。多云不是把所有东西都用所有云——而是保持出口门开着,让价格和可靠性保持诚实。

以 S3 兼容 API 作为共同基础

现在几乎每个对象存储服务商都支持 S3 API:AWS、Backblaze B2、Cloudflare R2、Wasabi、Google Cloud Storage(互操作模式)、Azure Blob(通过第三方网关),以及自托管的 MinIO 或 Ceph RGW。这意味着一个 SDK 覆盖所有:

import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
const r2 = new S3Client({
  region: 'auto',
  endpoint: 'https://account.r2.cloudflarestorage.com',
  credentials: { accessKeyId, secretAccessKey }
});
await r2.send(new PutObjectCommand({
  Bucket: 'transfers', Key: 'file.zip', Body: stream
}));

坚持使用 S3 API 子集(PUT、GET、LIST、DELETE、分段上传、预签名 URL)可获得完全可移植性。跳过服务商特定调用如 s3:GetObjectLegalHold,除非你有在每个后端支持该功能的计划。

在路由器后面抽象服务商

构建一个将逻辑路径映射到物理存储桶的小路由器。代码里是一个函数:

interface Store { put(key, stream); get(key); delete(key); }
class MultiCloudRouter implements Store {
  constructor(private index: Index, private stores: Record<string, Store>) {}
  async put(key: string, stream: ReadableStream) {
    const provider = chooseProvider(key);
    await this.stores[provider].put(key, stream);
    await this.index.record(key, provider);
  }
  async get(key: string) {
    const provider = await this.index.lookup(key);
    return this.stores[provider].get(key);
  }
}

chooseProvider 可以由策略驱动:区域亲和性、成本层、复制要求,或跨服务商的简单轮询。索引(Postgres 表或 DynamoDB)是对象位置的单一真实来源。

跨服务商的成本优化

价格差异巨大:

  • AWS S3 Standard:$0.023/GB存储,$0.09/GB出口
  • Cloudflare R2:$0.015/GB存储,出口免费
  • Backblaze B2:$0.006/GB存储,$0.01/GB出口
  • Wasabi:$0.0069/GB存储,出口免费(每月不超过存储量的1倍)
  • AWS S3 Glacier Deep Archive:$0.00099/GB存储,$0.02/GB出口+取回费

智能路由策略:

  • 面向用户的下载:R2(免出口费在这里无可竞争)
  • 冷归档:S3 Glacier Deep Archive
  • 区域冗余:B2(便宜、可靠,与 AWS 不同的企业风险面)
  • 长期保留合规副本:带对象锁的 Wasabi

对于每月向外传输50TB的文件传输服务,将出口从 S3 切换到 R2,在做任何其他优化之前每月节省约3.1万元。

跨服务商保持数据同步

对于需要跨服务商复制的关键数据,使用 rclone 的 sync 或 bisync

rclone sync r2:transfers b2:transfers-mirror --transfers 16 --checksum

持续复制方面,可用 AWS S3 跨区域复制(通过 Lambda 支持外部目标)或基于队列的复制器:每次 PUT 发布到 SQS/Kafka,消费者从队列读取并写入次级服务商。最终一致性,RPO 以分钟计。

不要复制所有内容。只复制无法重建的内容:用户上传的字节,是的;构建产物,可能不必要;同时存在于数据仓库中的分析日志,绝对不必要。

不出意外的凭证管理

多云意味着更多凭证,泄露的凭证是发生安全事件的方式。两条实践:

  • 集中式密钥存储:HashiCorp Vault、AWS Secrets Manager 或 Google Secret Manager。永远不要将密钥提交到 Git;在 CI 中用 gitleaks 扫描。
  • 短期、范围限定的令牌:优先使用 STS 令牌而非永久访问密钥。将每个凭证的范围限定到一个存储桶和所需的最少操作。

长期密钥按90天计划自动轮换,STS 1小时一轮换。用 ownerpurposeexpiry 标记每个密钥。每月检查孤立凭证。

统一监控与日志

跨服务商的可观测性比任何单一服务商内部的更重要。将所有服务商访问日志汇入一个统一接收端:

  • S3 服务器访问日志 → CloudWatch → OpenSearch
  • R2 访问日志 → Cloudflare Logpush → S3 → OpenSearch
  • B2 事件通知 → webhooks → Loki

统一仪表盘展示:每服务商请求量、错误率、p99延迟、每存储桶出口字节、近实时成本累计。当任何单一服务商超过预期日出口量的2倍时发出告警(这是泄露的预签名 URL 或爬虫滥用的良好信号)。

多云下的治理与合规

多云使合规面成倍增加。每个服务商都需要自己的数据处理协议、自己的次级处理方审查和自己的审计跟踪。实用步骤:

  • 将每种数据分类(公开、内部、机密、受限)映射到允许的服务商
  • 记录数据驻留:根据《个人信息保护法》(PIPL)和《数据安全法》(DSL),向境外传输数据需经网信办(CAC)安全评估或订立标准合同;跨境 GDPR 第44条同样要求有效机制(SCCs、充分性决定)
  • 追踪次级处理者。当服务商添加新的次级处理者时,你可能需要依据 PIPL 第21条或 GDPR 第28(2)条通知客户
  • 在主服务商之外备份审计日志——影响 CloudTrail 的 AWS 事件不应同时带走你的审计历史

在需要之前建立退出计划

可信的退出计划有三部分:每个依赖项的清单、经过测试的迁移脚本和出口预算。清单包括代码、IaC(锁定到服务商特定资源的 Terraform 模块)、IAM 策略、存储桶,以及任何 CDN 源站配置。迁移脚本应该每季度以干跑模式运行,避免脚本腐化。出口预算:按存储量的1.2倍规划,因为迁移过程中可能需要重新处理。

即便你从不切换服务商,一个经过演练的计划意味着合同续签谈判有分量,不可预见的价格上涨或服务变更也不会让团队瘫痪。

HexaTransfer 运行在 S3 兼容的存储层上,正是为了保持服务商选择的开放性——这一策略对任何传输大文件的团队同样有效。免费试用 hexatransfer.com——无需注册,单次最大10GB。

多云何时是过度设计

多云不是免费的。你为工程复杂性、重复工具和扩大的运营面付出代价。对于10名工程师以下、只有单一产品的团队,选一家服务商,协商批量折扣,把省下的复杂性投入产品。多云在满足以下三个门槛之一时才物有所值:合规要求跨司法管辖区的数据驻留,可靠性要求服务商级别的冗余(不只是区域),或者采购对单一厂商的谈判筹码对业务很重要。低于这些门槛,带干净抽象层和文件化退出计划的单云通常是务实之选。

通过端到端加密安全发送大文件

通过端到端加密免费传输最大10GB的文件。无需注册账户。文件在上传前在浏览器中加密,其他人无法读取。

发送文件