跨云对象存储迁移实战:从COS到OSS的百TB数据增量同步与校验
发布时间:2026/10/7 17:38:27 锦皓数字建站

前阵子刚完成了一次腾讯云COS到阿里云OSS的对象存储迁移。源桶里一百多TB数据、几千万个文件而且业务侧每天还有新增写入属于典型的“存量多、增量不停”的场景。跨云对象存储迁移本身的技术门槛不算高真正难的是方案取舍什么时候切、用什么工具、怎么保证数据一个不少、切完出了事怎么回滚。这篇文章把我这次实际执行的完整思路放出来覆盖方案选型、工具配置、参数调优、增量追平、业务切换和数据校验最后附一份常见问题速查表。无论你的桶是几个GB的小项目还是像我这种几十TB的存量业务照着这个思路做基本都能落地。1. 迁移前先算清这几笔账数据量、增量与成本很多同学一上来就找工具、配密钥觉得先把命令跑起来再说。我劝你先别急对象存储迁移跟搬数据库不一样它不要求强一致但受流量、请求数、文件数量的限制很明显。迁移前至少要把三笔账算清楚。1.1 数据量和文件数决定方案上限第一个参数是总容量第二个参数是文件总数后者往往比前者更致命。拿我这次源桶来说看控制台概览大概是一百多TB但真正让我头疼的是几千万个文件。对象存储的迁移瓶颈很少在带宽而在请求QPS。一个大文件比如5GB传输时一个请求就能搬完但如果是几千万个几十KB的小文件光遍历对象列表、逐个发起GET/PUT请求就要花掉大量时间。文件数决定了“多少轮请求”容量决定了“多少流量”两个维度都要统计。如果你对数据量没有底建议在迁移前用rclone跑一条很轻量的统计命令遍历一遍清单但不下载内容rclone size tencent:my-bucket这条命令会输出桶内的对象数量和总大小。数据量大、文件多也没关系它只是遍历metadata不会产生流量费。当然更快的方式是直接看腾讯云COS控制台的“基础配置-存储桶概览”或者配置COS清单功能生成一份CSV清单里面记录了对象的key、size、ETag、最后修改时间后面做数据校验也用得上。1.2 增量写入让“一次性迁移”变成“多轮同步”第二个要明确的问题源桶是不是只在迁移期间静止不动如果是备份归档类的静态数据一次性全量复制完就结束了。但大多数业务桶都有持续写入用户上传、日志推送、图片处理生成的新文件一直往里进。一旦有增量迁移策略就变了第一轮全量同步存量数据后续多轮增量同步把前一轮结束到当前时刻的新增文件追上来最后一轮在业务低峰期做“收口同步”让源桶和目标桶之间的差异趋近于零最后切换业务读写流量。所以工具必须支持“多次同步且能识别差异”不能每次全量重传。这个点在后面选型时会反复提到。我建议你在梳理需求时把源桶的日增增量多少GB、多少文件也写进文档里它会直接决定你需要预留多少同步窗口。1.3 流量和存储成本也要提前算第三个容易忽略的问题是钱。跨云迁移必然经过公网因为腾讯云COS和阿里云OSS之间没有内网直达通道。这里有个成本要点从腾讯云COS下载数据会产生下行流量费从阿里云OSS上传数据走公网入口则通常不收费因为OSS的“公网流入流量”免费。所以我的建议是迁移机放在腾讯云同区域拉取COS走内网流量免费再上传到OSSOSS的公网入口流入不额外计费整体成本压力小很多。反过来放在阿里云机器上拉COS就要走公网付下载流量费上传OSS走内网又享受不到免费入口反而多出一笔开销。顺带说一句如果是超大规模的数据量比如包年包月流量动辄几十TB可以再评估一下阿里云的在线数据迁移服务。那种方式适合一次性搬迁但对需要多轮增量追平、逐步灰度切换的场景不够灵活我最后还是选了手动工具加脚本控制的方案。1.4 四种主流方案对比迁移方案本质上就四类我把它们拉个表对比一下方便你对照自己的条件选方案适合规模增量支持断点续传成本上手难度rclone直连同步百GB到PB级天然支持多轮增量支持单文件分片上传、失败自动重试低仅需一台中转机中等ossutil配合URL拉取小批量、临时性不支持自动增量不支持拉取断点低低本地中转下载再上传几十GB内小数据不支持上传侧支持低中转耗时低业务双写切换大流量在线业务天然支持依赖代码健壮性高需改造代码高我这次选择的是“rclone直连同步”作为主方案。理由是它能同时覆盖全量和增量而且支持精细的并发控制、限速、断点续传和校验报告。业务双写那套说实话对存储桶这种低频读写的场景有点过度设计除非你的服务端逻辑本来就要做多活容灾否则不用考虑。2. 权限与依赖梳理迁移前最容易忽略的准备工作方案定了之后别急着跑同步先花半天时间把账号权限和数据依赖理清楚。这一步做得越细后面切换就越不慌。2.1 密钥与最小权限配置我的原则是绝不用主账号的密钥去配迁移工具。rclone的配置文件是明文的中转机万一被入侵泄露一套只读权限的密钥损失可控而且后期密钥更换只需要把子账号吊销不影响其他业务。腾讯云侧创建一个子账号只授予需要的COS读权限。你可以直接用现成的策略QcloudCOSReadOnlyAccess想要更收敛就自定义{ version: 2.0, statement: [ { effect: allow, action: [ cos:ListBucket, cos:GetObject, cos:GetBucketObjectVersions ], resource: qcs::cos:ap-shanghai:uid/123456:my-source-bucket/* } ] }这组权限允许列举桶对象、读取对象内容但不能删除、不能写足够迁移使用。阿里云侧同样创建RAM子账号并仅授权目标Bucket的写入能力{ Version: 1, Statement: [ { Effect: Allow, Action: [ oss:ListObjects, oss:PutObject, oss:GetObject ], Resource: [ acs:oss:*:*:my-dest-bucket, acs:oss:*:*:my-dest-bucket/* ] } ] }为什么连GetObject一起授权因为后续校验阶段要从目标桶读回对象做比对没有读权限就没法完成自查。最小权限不等于零权限够用的权限才是合适的。还有个小细节生成密钥时腾讯云的API密钥是SecretId和SecretKey两段阿里云是AccessKey ID和AccessKey Secret概念一一对应配置rclone时别填串了。这类低级错误我见过不止一次一查签名不对才反应过来。2.2 存量数据清单与依赖排查依赖排查是整个迁移里最容易被低估的环节。存储桶往往不止一个业务在用图床、附件、日志、备份、离线计算任务的中间结果都可能指向同一个桶。怎么摸清依赖两条路一是看访问日志。腾讯云COS可以开启日志投递把每个请求的访问IP、User-Agent、操作类型都记录下来。迁移前观察一到两天基本就能锁定哪些服务在持续读写这个桶。二是直接在团队里发一张表列出桶名、Region、自定义域名问谁在用。别嫌土这种排查方式最直接很多隐藏的消费方是靠人肉回忆找出来的。我这次就靠日志加人工确认梳理出一份依赖清单包含前端上传接口、图片处理服务、日志归档任务、离线分析脚本和两个管理后台。每项都标了读写类型、切换方式和责任人。后面切流时我只需要挨个确认这些服务已经指向新桶即可。2.3 域名、CDN与访问链路改造数据迁移只是换了个存储位置但业务访问的是域名链路上的改造比数据复制更容易翻车。要分三种情况处理直接使用Bucket默认域名。那迁移后把业务代码里的endpoint和bucket名改成OSS的即可改动点集中但琐碎。使用自定义域名CNAME到COS。那需要提前在阿里云OSS配置同名的自定义域名上传HTTPS证书然后等迁移完成后再改CNAME解析。这里有个坑如果CDN也参与了访问链路CNAME一改CDN回源地址如果不更新缓存节点仍然可能回源到老域名。通过CDN回源到COS。迁移后要把CDN的回源地址从COS域名改为OSS域名同时提前降低CDN缓存TTL或者直接做一次刷新预热避免切换后大量请求命中的是旧缓存。还有一个小建议在正式切换前几天把自定义域名的DNS TTL从默认值调低比如调到300秒。这样真正切域名时解析生效速度快回滚也快。如果等到切换当天才调TTLDNS缓存可能要很久才更新出问题想回滚都费劲。2.4 迁移前检查清单顺手整理一份我每次迁移前都要过一遍的清单源桶、目标桶的Region确认endpoint域名源端只读子账号密钥目标端读写子账号密钥迁移中转机位置确认能和源端走内网依赖消费方清单和责任人联系方式自定义域名、CDN域名、TTL值迁移期间的流量预算和成本预估回滚预案源桶保留只读的时间窗口、域名解析记录备份。这份清单看起来基础但我实测下来大部分迁移事故都出在这些“看起来基础”的环节上。3. 工具选型与配置实战rclone和ossutil怎么选、怎么配工具选型决定你后续三个礼拜是轻松还是痛苦。我在选型时把市面上能用的方案都过了一遍实际测试后留下了rclone作为主力ossutil作为小规模场景的备选。3.1 为什么主推rclone做跨云同步腾讯云官方确实有COS Migration、COSCMD这类工具但它们的定位是把本地或其他源的数据迁入腾讯云COS反向迁出或者做跨云同步不是它们的强项。阿里云侧也有数据在线迁移服务但整个流程偏向一次性搬迁对多轮增量追平和灰度切换的支持不够灵活。rclone能成为跨云对象存储迁移的首选核心原因有三点第一它是协议层工具支持把腾讯云COS当作S3兼容端点来读把阿里云OSS当作S3兼容端点来写底层的签名、分片、重试都封装好了。第二sync模式天然支持增量和差异比对可以反复执行每次只同步变化的文件。第三并发参数、限速参数、日志、校验报告一应俱全适合需要精细控制的大型迁移。所以我的结论是rclone直连同步适合绝大多数跨云对象存储场景。这也符合我这次实际执行下来的体验稳定、可控、可观测。3.2 rclone配置腾讯云COSS3兼容端点的正确姿势安装rclone这一步不展开各平台都有现成的二进制或安装脚本。重点看配置。执行rclone config选n新建remote类型选s3。然后有一大串provider选项一定要选TencentCOS。这个选项决定了签名算法和endpoint拼接方式选成AWS S3后面肯定会报签名不匹配。腾讯云那边的关键配置如下providerTencentCOSendpointhttps://cos.ap-shanghai.myqcloud.comaccess_key_id腾讯云子账号的SecretIdsecret_access_key腾讯云子账号的SecretKey注意endpoint不带bucket名格式是cos.region.myqcloud.com。如果你在北京就是cos.ap-beijing.myqcloud.com。Region代码取COS控制台里的地域简称别自己拼。配置完成后先用一条命令验证一下rclone lsd tencent:/能列出桶列表就算通了。如果报类似InvalidAccessKeyId或SignatureDoesNotMatch的错误优先检查密钥是不是填反了、provider是不是选的TencentCOS。3.3 rclone配置阿里云OSS与首次sync验证目标端阿里云OSS同样用s3类型配置provider选Alibabaendpoint填https://oss-cn-shanghai.aliyuncs.com。这里有个容易混淆的点阿里云OSS自己的API endpoint是oss-cn-shanghai.aliyuncs.comS3兼容endpoint也是同一个域名无需额外加s3.前缀。rclone的Alibaba provider会自动按OSS的S3兼容模式处理。配置好后同样验证rclone lsd ali:/两端的remote都通了我先不直接跑全量而是拿一个小桶或者一个子目录做一次验证性同步。比如先只同步一个前缀rclone sync tencent:my-bucket/dir-test ali:my-dest-bucket/dir-test \ --progress \ --transfers 16 \ --size-only同步完去目标桶随机检查几个文件确认内容能打开、路径没串位。这个验证过程花不了半小时但能提前暴露网络、权限、endpoint的问题避免大流量全量同步跑一半发现配置错误。我这次要是在全量时才验证估计要浪费好几天。3.4 常用参数详解transfers、checkers、size-only、bwlimitrclone参数很多但迁移场景里真正影响成败的就那么几个。--transfers是并发传输的文件数默认4。对于大文件场景建议适当调到16到32可以充分利用带宽。但别一味调高源端的对象存储对单IP的并发请求有限流调太高会触发限流导致大量重试反而变慢。--checkers是并发遍历目录的进程数默认8。小文件特别多的场景瓶颈往往在“列出哪些文件需要同步”不在传输本身。把checkers调到64甚至128遍历速度会明显加快。我这次源桶文件几千万个第一轮全量就是靠调高checkers跑完的。--size-only表示只看大小差异来决定要不要传输。这里解释一下为什么我常用size-only而不是默认的“大小修改时间”腾讯云COS和阿里云OSS对LastModified的精度、时区处理在跨云场景下有细微差别如果严格比对修改时间可能会把很多本应跳过的不变文件判断为“需要重传”白白浪费流量和时间。用size-only只要大小一致就跳过虽然理论上可能漏掉“大小没变但内容变了”的文件但对象存储文件不可变是基本约定这种概率极低。如果真的很在意内容一致性可以用--checksum它会读取两端对象的ETag做对比但代价是每次同步都要额外请求一遍源对象元数据小文件多时会显著拖慢速度。--bwlimit是限速参数比如--bwlimit 100M限制到100Mbps。生产环境迁移建议限一下速避免把出口带宽占满影响线上业务。一个实际用法是组合使用rclone sync tencent:my-bucket ali:my-dest-bucket \ --progress \ --transfers 16 \ --checkers 64 \ --size-only \ --bwlimit 00:00,50M 09:00,200M 18:00,50M \ --log-file /var/log/cos2oss.log \ --log-level INFO日志一定要开着后面排查问题全靠它。tail -f观察实时进度关注日志里有没有大量ERROR如果有先停下来查原因不要让它带病跑完。3.5 ossutil和本地中转小规模场景的备选打法rclone虽好但有些小规模场景用ossutil更轻。比如你只有一个几GB的临时目录需要迁到OSS没必要搭一套rclone配置。ossutil是阿里云官方的命令行工具配置交互式完成ossutil config按提示输入endpoint、AccessKey ID、AccessKey Secret。然后可以用它从腾讯云COS生成的预签名URL拉取文件到OSSossutil cp https://my-bucket.cos.ap-shanghai.myqcloud.com/path/file?signaturexxx oss://my-dest-bucket/path/file但这种URL方式有几个限制预签名URL有效期通常按小时计过期就要重新生成也不适合成批量处理脚本循环一个个拉取会很痛苦。所以它只适合十来个小文件临时搬迁。如果文件数不多但总量在几十GB也可以走“本地中转”用COSCMD或rclone下载到中转机磁盘再用ossutil上传到OSS。注意中转机磁盘要留够空间上传完成后及时清理。简单总结一下工具选择逻辑数据量过TB、文件数过万直接上rclone数据量很小、一次性处理用ossutil更顺手。不要为了工具多样性浪费精力。4. 从全量同步到增量追平迁移执行与校验细节配置完成只是开始接下来的执行节奏和校验方法才是决定迁移质量的关键。4.1 第一轮全量同步怎么跑全量同步之前先确认中转机选的位置。我这次放在腾讯云同区域目的就是拉COS走内网免流量费。中转机的带宽建议按目标规划比如期望迁移速度在300Mbps左右中转机带宽至少要500Mbps不然机器带宽成了瓶颈工具参数调再高也没用。第一轮全量同步的命令与前面验证命令类似只是去掉子目录限制跑整个桶rclone sync tencent:my-bucket ali:my-dest-bucket \ --progress \ --transfers 16 \ --checkers 64 \ --size-only \ --bwlimit 00:00,50M 09:00,200M 18:00,50M \ --log-file /var/log/cos2oss.log \ --log-level INFO跑的时候盯三件事日志里的Error数量、目标桶容量变化趋势、中转机的带宽和负载。Error数量如果持续增长不要抱着“后面再修”的心态。常见原因包括个别对象权限异常、对象名包含特殊字符导致签名失败、源端临时限流等。先暂停同步针对报错的对象单独排查。我建议把日志里error的行提取出来单独看grep ERROR /var/log/cos2oss.log | head -100小文件特别多的桶第一轮全量可能要跑很多天。这时候建议把日志按天轮转或者每天记录一次已同步的文件数、总量形成迁移日报。rclone本身不提供断点续传的“进度保存”概念但sync模式是幂等的中断后重新跑已完成的对象会通过size对比直接跳过所以中断不可怕放心重启。4.2 增量追平到什么程度才算“干净”第一轮全量结束后源桶很可能又出现了新的文件这时候进入增量追平阶段。做法很简单隔一段时间再跑一次sync这次传输的文件数和流量应该远小于全量。那怎么判断追平了我的经验是连续跑两轮sync第二轮传输的对象数量为0或者只差几个还在写入中的临时文件就可以认为追平了。注意增量同步会有一个“追不上”的尾巴业务写多少sync就追多少如果写入频率很高sync和写入交替进行永远会差几个刚写进去的文件。这个问题需要通过“收口”来解决。收口的意思是在业务低峰期短暂停止源桶的写操作或者让写入方切到只读模式然后跑最后一轮sync把最后一点差异拉平再切换业务流量。如果业务完全不能停那就只能接受“切流后还有少量文件在源桶”的现实用双写或者异步任务把尾部数据补过来。我在这次迁移中选了可控的收口方案凌晨低峰期暂停上传接口15分钟跑完最后一次sync立刻切流。4.3 灰度切换与回滚机制迁移工具跑得再顺畅切换环节还是得按灰度方式来。我的切换顺序是先切读再切写。所谓切读是把需要读取存量资源的服务图片访问、附件下载、静态资源加载先指向OSS。这些服务通常是只读的切换失败影响面小且容易发现。具体做法是在配置中心或代码里把Bucket域名、endpoint切换为目标桶。观察一段时间确认读路径没有问题再切上传、写入接口。每一步切换前都先把源桶的只读保留期确定下来。我的习惯是源桶至少保留一到两周的只读状态期间DNS记录、旧endpoint配置都备份好。一旦OSS侧出现严重故障可以靠改配置把流量切回去。注意回滚不是重新跑一遍迁移而是把配置指回源桶。所以配置管理要规范化不要手动在各种服务器里改配置最好收敛到一个配置中心或环境变量。还有一类“隐藏的服务”特别容易漏掉日志归档、定时备份、离线计算任务。这些任务往往没有交互式页面跑在定时调度或者cron里。切换时如果只改了主站配置忘了改这些任务等它们半夜跑起来又会把新增文件写回COS里。所以依赖清单那张表必须挨个勾选确认。4.4 数据校验不只是对比文件数数据校验是整个迁移里最容易被敷衍的环节。很多人只对比一个总数源桶多少个对象目标桶多少个对象对得上就宣布成功。文件数一致不代表内容一致路径级的一致才是关键。我的校验分三层第一层数量级校验。用rclone size分别统计两端桶的对象数和总大小先看量级是否对得上。第二层路径级校验。用rclone check对比两端目录rclone check tencent:my-bucket ali:my-dest-bucket \ --size-only \ --log-file /var/log/cos2oss-check.log \ --log-level INFO如果只有size差异会直接报告哪些文件不一致同时输出一个汇总。注意check命令也要遍历全量目录以源桶几千万文件的数量级跑完也需要一定时间建议放在收口后、切流前执行。第三层抽样内容校验。对于图片、视频、普通压缩包这类文件size加抽查基本够用。但对于账单、数据导出、模型文件这类关键对象可以用下载后计算MD5的方式抽验。这里提醒一句腾讯云COS和阿里云OSS的ETag如果是分片上传生成的并不等同于对象的MD5。所以拿源桶ETag和目标桶ETag直接对比遇到分片上传的对象可能会误报。我这次的做法是对关键目录下的文件抽取10%左右用脚本下载到本地算MD5再和源端拉一次MD5对比。整体校验结果和rclone check一致才算真正放心。5. 切换后的坑与收尾常见问题速查和个人避坑记录这一段是这次迁移里最值钱的部分把我在执行中实际碰到的问题和最终确认的解决办法列出来。你之后大概率也会遇到其中几个。5.1 常见问题速查表现象可能原因解决办法rclone报SignatureDoesNotMatchrclone的provider选错签名算法不匹配确认COS配TencentCOS、OSS配Alibaba同步时报AccessDenied源端或目标端密钥权限不足按最小权限模板重新授权补充GetObject/ListObjects文件数对不上目标比源少增量期间新文件产生或部分对象同步失败被跳过先看日志中ERROR行对失败对象重跑再跑一轮sync追增量文件大小对不上大文件上传分片丢失或源端对象变化用rclone check定位具体文件单独重试URL拉取迁移时提示签名过期预签名URL有效期太短改用rclone同步或脚本重新生成URL迁移速度远低于带宽预期transfers/checkers并发过低或源端限流调大checkers观察源端QPS合理设置transfers切换域名后部分用户还是访问到旧桶CDN缓存或DNS缓存未失效提前调低TTL切换后刷新CDN必要时通知客户端强刷宝塔面板或WordPress插件改完AccessKey不生效配置没实际写入或缓存了旧配置确认配置保存的位置重启相关服务或PHP进程几个最容易踩的细节我再单独强调一下宝塔面板这类图形化管理工具修改OSS的AccessKey ID和Secret后页面提示已保存但实际服务进程可能还在用旧配置。我在迁移后更新WordPress附件地址时遇到过类似情况最后是靠重启面板相关服务解决的。改完配置一定要验证别只信界面提示。目标桶的Bucket命名空间是全球唯一的如果你的目标桶名和某个已存在的Bucket重名创建会直接失败需要换一个后缀比如加-migrated。腾讯云COS的S3兼容endpoint走的是公网从阿里云侧访问时网络质量可能一般迁移机放腾讯云同区域能显著降低延迟。5.2 我踩过的三个坑第一个坑是rclone provider选成了AWS S3。第一次配置COS时我顺手选了provider为AWS结果跑了不到一分钟就报签名错误。后来查文档才确认腾讯云COS虽然兼容S3 API但签名算法细节和标准AWS S3有差异rclone专门用TencentCOS这个provider处理。这个错误其实很容易犯因为大家习惯了S3协议的统一性。第二个坑是全量同步时小文件拖垮速度。我第一轮全量同步用默认参数跑几天时间才跑了不到一半日志显示大量时间花在遍历目录上。后来把checkers调到64transfers也提高到16同步速度明显改善。小文件多的桶遍历效率才是第一瓶颈传输通道数量过多反而容易触发源端限流。第三个坑是切流时CDN缓存。我改了自定义域名的CNAME指向OSS也更新了CDN回源地址但业务侧反馈部分图片仍然加载很慢看起来像没切成功。排查发现是CDN节点上还缓存着旧资源缓存TTL又设的过长。最后把相关目录的缓存刷新了一轮又等缓存过期才恢复。这个坑提醒我凡是域名链路涉及CDN的迁移前一周就要把TTL调低切换当天做刷新预热。5.3 源桶关停前的收尾检查迁移完成不等于可以立刻把源桶删掉。我的收尾流程分三步第一步源桶改成只读。给腾讯云COS源桶加上写权限禁止策略确保没有业务再写入新数据。这一步可以防止“幽灵写入”在不知情的情况下继续往源桶灌数据。第二步观察一到两天。看OSS侧是否出现文件数量增长、访问错误是否增多确认业务全部正常后再进入关停阶段。第三步清理源桶。删除前记得先清空桶内数据因为很多云服务商不允许直接删除非空桶。删除后同名Bucket能否重新创建要看厂商规则所以建议清理前把容器名、域名信息完整备份别删完才发现需要复用。另外别忘了把监控和告警从COS侧迁移到OSS侧。阿里云OSS控制台可以配置基础监控项比如存储容量、请求数、4xx/5xx错误率再配上阈值告警。迁移后如果业务有异常OSS的监控指标能第一时间暴露问题而不是等用户反馈太久才发现。最后说一个我个人很坚持的习惯把整个迁移过程整理成一份文档包括方案对比、命令记录、参数选择、问题处理日志。不是给领导看的而是给下次迁移时的自己看的。对象存储迁移这个事工具和平台的细节会变但踩坑的套路基本类似。文档里多记录一条CHECKLIST下次就能少失眠一晚上。
锦
锦皓数字建站
深耕本土企业品牌数字化升级,专注原创端正雅致商务官网,从视觉设计到稳定运维全程保驾护航。