ScyllaDB 迁移实录:12TB 数据切流,四个阶段完整跑通 📅 发布时间:2026/9/11 17:03:50 👁 浏览次数: ScyllaDB 迁移实录12TB 数据切流四个阶段完整跑通【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb大促前 7 天DBA 接到死线12TB 业务数据完成 Cassandra 迁移 ScyllaDB期间业务流量不许中断。本文是一次跑完全流程的迁移实录只讲四个风险点上的操作schema 冻结、快照灌数、双写跑通、校验切流每一步都能直接照做。迁移前先问自己 3 个问题答案是否就缓一缓动手前得先判断该不该迁这件事比性能提升更要命。问一现有集群的读写链路是否真有压力如果当前集群扛峰值毫无压力又没有大体量新业务排期迁移成本应用双写改造、观察期值守就是纯亏损。迁移是个以周为单位的项目不是拧个配置就能回滚的开关。问二业务是否重度依赖 ScyllaDB 不兼容的特性比如还在用 Thrift 接口接入ScyllaDB 6.0 已移除或者表里存着 Cassandra 2.0 时代的本地计数器旧格式不支持。有这类依赖先改业务否则迁移做到一半会卡死。对照矩阵见 Cassandra 兼容性说明。问三团队能不能腾出两周做双写和双读零停机方案里七成时间花在应用改造和数据校验上工具只占三成。人手排不开不如等低峰期做一次停机迁移——它比仓促的零停机方案风险更小。迁移工具选型30 秒定方案的对比表别看工具名气先看数据形态路径其实就三条迁移路径数据形态应用是否停服典型耗时TB 级主要代价sstableloader 快照导入源端 SSTable不停服1–3 天中间节点带宽、loader 运维Spark MigratorCQL 转 CQL全量 CQL 读写不停服3–7 天源集群双倍读压力可做字段变换停机拷贝快照→导入源端 SSTable需维护窗口数小时流程最简单但有停机窗口说人话想要不停服sstableloader 是默认解中途要改 schema 或换字段结构上 Spark Migrator停机拷贝留作兜底别在大促前试它。从快照到切流量ScyllaDB 零停机迁移的四条风险线全程按风险线拆成四个阶段顺序固定A 冻结构、B 灌存量、C 跑增量、D 校验后切。顺序对了每个阶段的失败面才隔离得开。Phase Aschema 冻结先冻结构再动数据。源端导出全量 schema人工调整不兼容参数后导入cqlsh cassandra-ip -e DESC SCHEMA orig_schema.cql # 调整参数后导入目标集群 cqlsh scylla-ip -f adjusted_schema.cql参数改动三处是高频雷点crc_check_chance整行删掉compression行改成sstable_compressionspeculative_retry里的99PERCENTILE必须写成99.0PERCENTILE。顺手把待迁移表的min_threshold提到 2、gc_grace_seconds拉到 10 年防止迁移期间删除标记tombstone被清掉。✅ 检查点新集群逐表核对 keyspace 与表名cqlsh 连上无任何报错。Phase B灌历史数据源端按表打快照拷到独立中间节点再用 sstableloader 并行灌入。别在 ScyllaDB 集群上直接跑导入会抢生产流量# 1) 源端各节点打快照 nodetool snapshot -t mig keyspace # 2) 快照目录挂到中间节点路径必须以 /keyspace/table 结尾 sudo mount cass-ip:/var/lib/cassandra/data/ks/tbl-*/snapshots/mig /mnt/mig/ks/tbl # 3) 每表一个 loader-t 限制单实例带宽Mbit/s sstableloader -d scylla-ip1,scylla-ip2 -t 4000 /mnt/mig/ks/tbl并发按一次一个 keyspace、keys 内多实例组织-d带上全部 ScyllaDB 节点工具自己按环分发。sstableloader 性能调优的关键就在这-t管单实例带宽实例数管并发两者别混用。实例挂了直接重跑重复数据会被 compaction 收掉。✅ 检查点两端SELECT COUNT(*)同量级loader 日志无卡死任务。Phase C双写跑通应用改为同时写两个集群读仍走旧库。这是 Cassandra 双写切换方案的核心两个硬要求时间戳必须由客户端生成两端服务器时钟差毫秒级交给服务端会误判脏数据失败写入进重试队列不许静默丢futs [cass_sess.execute_async(stmt, vals), scylla_sess.execute_async(stmt, vals)] fails [] for i, f in enumerate(futs): try: f.result() except Exception as e: fails.append(i) log.error(dual write failed on %s: %s, (cassandra, scylla)[i], e) if fails: retry_queue.put(vals)先放 1 小时生产流量试跑确认链路热了再进入下一阶段。✅ 检查点双写失败率 0.01%重试队列能清空。Phase D校验与切流校验分两层粗比是两边各跑一遍SELECT COUNT(*) FROM ks.tbl差值要能用迁移期间的新写入解释细比靠抽样每轮 1000 行bad 0 for _ in range(1000): pk random_key() a, b cass_get(pk), scylla_get(pk) if a ! b: bad 1 log_mismatch(pk, a, b) print(error rate:, bad / 10) # 0.1% 才允许切流切流走三段读 10% → 读 100% → 读写全上新集群每段观察 24 小时。硬线只有一条错误率不到 0.1% 以下读写开关一律不动。✅ 检查点全量读写落新集群旧集群只读挂起双写开关可一键关闭回滚。踩坑实录3 个故障现场还原抽样比对报出一大片不一致。数据其实是一致的——比对时取了各自服务端生成的写入时间两个集群时钟差着几毫秒比对必挂。后来统一改成客户端生成时间戳错误率当场归零。一张表导入死活不动loader 日志报错。排查半天这张表在源端开了静态加密sstableloader 压根不支持加载加密文件。修法绕源端先解密表、nodetool 升级 SSTable 格式再重跑导入。做迁移排期时务必逐表确认加密状态。切流后第 3 天有数据复活了——新集群上的 tombstone 被 compaction 清掉旧库已删的数据又显示出来。根子是迁移期间没拉高gc_grace_seconds。改成 10 年之后这类问题再没出现过。切流后 48 小时运维清单这么交接交给值班同事前下面 6 项逐条过一项都别省 compaction 积压回落基线sstable 文件数量无异常增长⏱️ 迁移表的min_threshold、gc_grace_seconds改回原值✅ 双写开关已关应用侧无指向旧集群的残留连接 ScyllaDB 侧做一次全量快照这是本次迁移最后的保险️ 旧集群不拆保持只读观察两周作为比对与回滚对象 新集群告警阈值已同步值班同学首轮 oncall 由迁移团队兜底收尾完整流程细节在官方文档里Cassandra 到 ScyllaDB 迁移流程讲全链路sstableloader 手册查参数。遇到文档没写的问题直接去项目仓库提 issue或者到社区邮件列表问维护者回复挺积极。迁移和运维一样切流那天只是开始祝顺利。【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考