ScyllaDB 复制策略迁移指南:从 SimpleStrategy 切换到 NetworkTopologyStrategy 的无停机与停机两种方案
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
导读
本文基于 ScyllaDB 官方操作手册中的集群管理流程,完整讲解如何将一个使用SimpleStrategy复制策略的 keyspace 安全迁移到NetworkTopologyStrategy。你将掌握:何时可以选择无停机迁移、何时必须停机操作、如何通过 CQL 修改复制策略、如何配套完成 snitch 切换与cassandra-rackdc.properties配置,以及迁移背后 ScyllaDB 两种复制策略在源码层面的实现差异。迁移完成后,你的集群将具备跨数据中心(DC)、跨机架(rack)的拓扑感知复制能力,这是生产环境部署的基本要求。
为什么需要从 SimpleStrategy 切换到 NetworkTopologyStrategy
SimpleStrategy是 Cassandra 兼容模型中最早的复制策略:它在 token 环上顺序选取下一个拥有 token 的节点作为副本,完全不感知数据中心与机架的物理拓扑。在 locator/simple_strategy.cc 的calculate_natural_endpoints()实现中可以看到,它只是沿tm.ring_range(t)遍历排序后的 token 环,取前replication_factor个节点即作为副本集合,既不看 DC 也不看 rack:
for (auto& token : tm.ring_range(t)) { if (endpoints.size() == replicas || endpoints.size() == tm.count_normal_token_owners()) { break; } auto ep = tm.get_endpoint(token); endpoints.push_back(*ep); co_await coroutine::maybe_yield(); }这带来的直接问题是:一旦集群跨多个机架甚至跨数据中心部署,SimpleStrategy可能把所有副本都落在同一个机架或同一个 DC 上,机架/DC 级故障就会造成全部副本同时不可用。此外,从源码还可以确认SimpleStrategy的另外两个限制:
- 不支持 tablet 复制:
validate_options()中显式抛出"SimpleStrategy doesn't support tablet replication"(见 locator/simple_strategy.cc); - 只有
replication_factor一个合法选项,且必须是数值,否则抛出configuration_exception。
因此,官方文档明确建议:不要在生产环境使用SimpleStrategy,新建集群时应直接采用NetworkTopologyStrategy(见 update-topology-strategy-from-simple-to-network.rst)。
NetworkTopologyStrategy则完全不同。在 locator/network_topology_strategy.cc 中,其构造函数把配置中的每个DC:RF键值对解析进_dc_rep_factor映射,并累加得到总复制因子;而在calculate_natural_endpoints()中,natural_endpoints_tracker会按 DC 分别统计 token owner 与 rack 分布,优先把副本分散到不同机架("Replicas are put into separate racks while possible"),从而真正实现拓扑感知复制。同时 locator/tablets.cc 中的注释也表明:tablets 只能与NetworkTopologyStrategy配合使用。这意味着迁移到NetworkTopologyStrategy也是后续启用 tablet 能力的前提。
第一步:判断你的场景属于哪条迁移路径
在动手之前,先根据集群拓扑和复制因子(RF)的变化情况,判断应该采用哪条迁移流程。官方给出了两条互斥的路径:
无停机迁移(Procedure with no downtime)
满足以下任一条件即可使用无停机方案:
- 所有节点都在同一个 rack 上;或者
- 无论 rack 数量多少,
SimpleStrategykeyspace 的 RF 不发生变化,且 RF 恰好等于集群节点总数。例如:某 keyspace 的 RF 为 3、集群恰好 3 个节点,且 RF 保持不变,那么 rack 数量多少都无所谓。
为什么 RF 等于节点数时无需停机?因为此时每个 token 的副本集覆盖了环上所有节点,切换到NetworkTopologyStrategy后新的副本集合与旧集合一致,数据不会发生“搬移”。
停机迁移(Procedure with downtime)
满足以下任一条件,就必须走停机方案:
- 集群节点分布在多个 rack 上,且 RF 保持不变,但 RF 不等于集群节点总数;
- 集群节点分布在多个 rack 上,且 RF 发生变化。
原因是:新策略在跨 rack 时会选择与SimpleStrategy不同的节点作为副本,旧副本上的一部分数据将不再被新副本集合覆盖,需要停机后通过两轮 full repair 与 cleanup 来纠正,否则可能丢失数据。
如何确认节点的 rack 分布
使用nodetool status查看每个节点所属的 DC 与 rack;如果部署了 Scylla Manager,也可以从 Manager 节点上执行sctool status获得相同信息:
nodetool status输出中的RACK列会显示每个节点的机架归属。这一步直接决定你走哪条迁移路径,务必先执行。
第二步:找出所有仍在用 SimpleStrategy 的 keyspace
SimpleStrategy不仅可能出现在用户自建的 keyspace 中,也可能出现在部分系统 keyspace 中,必须逐一排查。
检查用户自建 keyspace
查看某个具体 keyspace 的复制策略:
DESCRIBE KEYSPACE mykeyspace;一次性查看全部 keyspace:
DESCRIBE SCHEMA;检查系统 keyspace
以下系统 keyspace 默认可能使用SimpleStrategy,需要单独确认:
DESCRIBE KEYSPACE system_distributed; DESCRIBE KEYSPACE system_traces; DESCRIBE KEYSPACE system_audit;以system_distributed为例,在 db/system_distributed_keyspace.cc 的源码中可以看到该 keyspace 的复制配置确实使用了org.apache.cassandra.locator.SimpleStrategy这一注册名。ScyllaDB 通过utils/class_registrator.hh机制将字符串类名注册到策略工厂:SimpleStrategy同时注册了全限定名org.apache.cassandra.locator.SimpleStrategy和短名SimpleStrategy(见 locator/simple_strategy.cc),因此 CQL 中两种写法均合法。
只要上述任一 keyspace 显示使用SimpleStrategy,就按本文对应的流程切换到NetworkTopologyStrategy。注意官方文档原文中 "NetworkTopologyStategy" 为笔误,正确拼写为NetworkTopologyStrategy。
方案一:无停机迁移(推荐条件满足时使用)
无停机流程非常简洁,核心就一步:逐个修改 keyspace 的复制策略。
修改 keyspace 复制策略
以一个名为mykeyspace的 keyspace 为例,迁移前(Before)的状态为:
DESCRIBE KEYSPACE mykeyspace; CREATE KEYSPACE mykeyspace WITH replication = { 'class' : 'SimpleStrategy', 'replication_factor': '3'};执行 ALTER 命令将其改为NetworkTopologyStrategy,其中<existing_dc>替换为集群中实际存在的数据中心名称,3为该 DC 的目标 RF:
ALTER KEYSPACE mykeyspace WITH replication = { 'class' : 'NetworkTopologyStrategy', '<existing_dc>' : 3};迁移后(After)再次确认:
DESCRIBE KEYSPACE mykeyspace; CREATE KEYSPACE mykeyspace WITH replication = { 'class' : 'NetworkTopologyStrategy', '<existing_dc>' : 3};从 locator/network_topology_strategy.cc 的validate_options()可以知道,ALTER 时传入的每个 DC 名称都必须存在于集群当前拓扑(topology.get_datacenter_racks())中,否则会抛出Unrecognized strategy option {...}的configuration_exception;同时check_enough_endpoints()会校验每个 DC 的 RF 不能超过该 DC 实际的 token owner 节点数,否则抛出Datacenter {} doesn't have enough token-owning nodes for replication_factor={}。所以请确保<existing_dc>与 RF 取值与集群实际一致。
另外注意:NetworkTopologyStrategy不接受replication_factor这种扁平写法,必须展开为DC:RF列表(源码中直接对replication_factor键触发on_internal_error)。如果集群有多个 DC,应写成类似{'class':'NetworkTopologyStrategy', 'dc1':3, 'dc2':3}的形式。
配套完成 snitch 切换与 rackdc 配置
修改复制策略只是第一步,要让NetworkTopologyStrategy真正按 DC/rack 工作,还需要确保 snitch 与节点拓扑信息一致,操作步骤详见 switch-snitch.rst:
在
/etc/scylla/scylla.yaml中把endpoint_snitch改为支持拓扑感知的 snitch,例如:endpoint_snitch: GossipingPropertyFileSnitch编辑
/etc/scylla/cassandra-rackdc.properties,填写每个节点所属的 DC 与 rack,并设置首选 DC 名称。仓库中的 conf/cassandra-rackdc.properties 给出了该文件的完整注释模板:dc=my_data_center rack=my_rack prefer_local=<false | true> dc_suffix=<Data Center name suffix, used by EC2SnitchXXX snitches>注意该文件允许 DC 与 rack 名称包含空格(首尾空格会被自动裁剪);
prefer_local用于控制是否优先选择本地 DC 的副本进行读取。云环境场景(如Ec2MultiRegionSnitch)中,DC 名通常就是 region 名、rack 名就是可用区(AZ)。
注意:switch-snitch 文档同时指出,切换 snitch 通常需要集群完全停机,因此强烈建议在集群搭建阶段就选对 snitch;无停机迁移只保证复制策略切换这一环节无需停机,snitch 切换环节需按其文档要求另行安排。同时,切换后的 snitch 必须指定与之前相同的 DC 与 rack。
方案二:停机迁移(多 rack 且 RF 不等于节点数时必须使用)
当集群跨多个 rack 且 RF 不等于节点总数、或 RF 本身需要调整时,新策略选出的副本节点会与旧策略不同,直接 ALTER 会导致部分数据失去副本覆盖,因此官方流程要求先停止全部流量、进行集群完全停机,按以下顺序操作:
停止集群的全部流量。这一步是硬性要求,文档明确警告:"A failure to stop the traffic can cause data loss."(未停止流量可能导致数据丢失)。
对集群执行一次 full repair。repair 的作用是让所有副本数据达成一致,具体命令与原理参见 repair.rst:ScyllaDB 采用 row-level repair,逐行计算校验和并通过集合对账算法只交换不一致的行,最小化网络传输与磁盘读取。可手动执行
nodetool repair,或使用 Scylla Manager 调度。按上文“方案一”中的 ALTER 命令修改复制策略(
ALTER KEYSPACE ... WITH replication = {'class':'NetworkTopologyStrategy', '<existing_dc>':3})。再执行一次 full repair。策略切换后新副本集合需要与旧副本对齐,第二次 full repair 负责把数据同步到新选出的副本节点。
在每个节点上执行
nodetool cleanup。cleanup 用于清理那些不再属于本节点 token 范围的陈旧数据(该命令的完整说明见 cleanup.rst),避免切换后旧副本残留垃圾数据占用磁盘。恢复流量。
完成上述步骤后,同样需要按“方案一”中的说明完成 snitch 切换、编辑cassandra-rackdc.properties并设置首选 DC 名称,整个迁移才算闭环。
为什么需要两轮 repair + cleanup
从副本集合的角度解释:第一轮 repair 保证“切换前”所有副本数据一致;ALTER 之后NetworkTopologyStrategy重新计算自然端点(natural endpoints),部分 token 的副本节点发生变化;第二轮 repair 保证新副本集合从旧副本补齐数据;最后nodetool cleanup清除原副本节点上不再属于它的数据。三步缺一不可,这是停机方案“更复杂”的本质原因——拓扑变化改变了数据的物理分布。
迁移后的验证与日常维护建议
迁移完成后,建议做以下验证:
- 再次执行
DESCRIBE SCHEMA或DESCRIBE KEYSPACE <name>,确认所有用户 keyspace 与system_distributed、system_traces、system_audit均已切换为NetworkTopologyStrategy; - 执行
nodetool status确认每个节点上报的 DC/rack 与cassandra-rackdc.properties一致; - 结合 repair.rst 的建议,将 repair 纳入日常运维:定期执行
nodetool repair -pr(逐节点顺序执行),删除频繁的场景下间隔应小于gc_grace_seconds(默认 10 天),例如每周一次。
总结
从SimpleStrategy迁移到NetworkTopologyStrategy是 ScyllaDB 生产化的关键一步:前者在源码层面完全不感知 DC/rack,无法支撑跨机架容灾,也不支持 tablet;后者按 DC 独立计算 RF 并在 rack 间分散副本,是生产环境与 tablet 功能的基石。迁移路径的选择完全取决于拓扑与 RF 的关系——同 rack、或 RF 等于节点数时走无停机方案,仅需逐个ALTER KEYSPACE;多 rack 且 RF 不等于节点数、或 RF 调整时,必须停机并按“full repair → ALTER → full repair → cleanup”的顺序操作。最后不要忘记配套切换 snitch 并配置cassandra-rackdc.properties,并在日常运维中坚持定期 repair。
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考