复制策略 #
一、复制概述 #
1.1 什么是复制 #
复制是将数据存储在多个节点上的机制,提供数据冗余和高可用性。
text
数据复制示意图:
┌─────────────────────────────────────────────────────────┐
│ │
│ 原始数据 │
│ ┌─────────┐ │
│ │ Data A │ │
│ └────┬────┘ │
│ │ │
│ ▼ 复制 │
│ ┌────┴────────────────────────┐ │
│ │ │ │ │ │
│ ▼ ▼ ▼ ▼ │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Rep 1│ │Rep 2│ │Rep 3│ RF=3 │
│ │Node1│ │Node2│ │Node3│ │
│ └─────┘ └─────┘ └─────┘ │
│ │
└─────────────────────────────────────────────────────────┘
1.2 复制的作用 #
| 作用 | 说明 |
|---|---|
| 高可用 | 节点故障时数据仍可访问 |
| 容灾 | 数据中心故障时数据保护 |
| 读性能 | 就近读取副本数据 |
| 负载均衡 | 分散读取请求 |
二、复制因子 #
2.1 复制因子概念 #
复制因子(Replication Factor, RF)定义了每条数据存储的副本数量。
text
复制因子说明:
┌─────────────────────────────────────────────────────────┐
│ │
│ RF=1: 每条数据存储1份 │
│ ┌─────────┐ │
│ │ Data │ │
│ └─────────┘ │
│ 风险:节点故障数据丢失 │
│ │
│ RF=3: 每条数据存储3份(推荐) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Data │ │ Data │ │ Data │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ 优点:可容忍1个节点故障 │
│ │
│ RF=5: 每条数据存储5份 │
│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Data │ │Data │ │Data │ │Data │ │Data │ │
│ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │
│ 优点:可容忍2个节点故障 │
│ │
└─────────────────────────────────────────────────────────┘
2.2 复制因子选择 #
| RF | 容错能力 | 存储开销 | 适用场景 |
|---|---|---|---|
| 1 | 0 | 1x | 开发测试 |
| 2 | 1 | 2x | 小型生产 |
| 3 | 1 | 3x | 标准生产(推荐) |
| 5 | 2 | 5x | 关键业务 |
三、SimpleStrategy #
3.1 概述 #
SimpleStrategy是简单的复制策略,适用于单数据中心场景。
text
SimpleStrategy复制:
┌─────────────────────────────────────────────────────────┐
│ │
│ Token Ring (顺时针方向) │
│ │
│ Node A ──────▶ Node B ──────▶ Node C │
│ Token 1 Token 2 Token 3 │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Rep 1│ │Rep 2│ │Rep 3│ │
│ └─────┘ └─────┘ └─────┘ │
│ │
│ 副本按Token顺序顺时针分布 │
│ │
└─────────────────────────────────────────────────────────┘
3.2 创建键空间 #
sql
-- 使用SimpleStrategy创建键空间
CREATE KEYSPACE my_keyspace
WITH replication = {
'class': 'SimpleStrategy',
'replication_factor': 3
};
-- 修改复制因子
ALTER KEYSPACE my_keyspace
WITH replication = {
'class': 'SimpleStrategy',
'replication_factor': 5
};
3.3 副本放置规则 #
text
SimpleStrategy副本放置:
┌─────────────────────────────────────────────────────────┐
│ │
│ 假设:RF=3,节点顺序为 A -> B -> C -> D -> E │
│ │
│ 数据Token落在节点A范围: │
│ ├── 第1个副本:Node A │
│ ├── 第2个副本:Node B(顺时针下一个) │
│ └── 第3个副本:Node C(顺时针下两个) │
│ │
│ 注意:不考虑机架/数据中心拓扑 │
│ │
└─────────────────────────────────────────────────────────┘
3.4 优缺点 #
| 优点 | 缺点 |
|---|---|
| 配置简单 | 不考虑拓扑结构 |
| 适合单数据中心 | 多数据中心场景不适用 |
| 易于理解 | 机架故障风险 |
四、NetworkTopologyStrategy #
4.1 概述 #
NetworkTopologyStrategy考虑数据中心和机架拓扑,适用于多数据中心场景。
text
NetworkTopologyStrategy复制:
┌─────────────────────────────────────────────────────────┐
│ │
│ Datacenter 1 Datacenter 2 │
│ ┌─────────────────────┐ ┌─────────────────────┐ │
│ │ Rack 1 Rack 2 │ │ Rack 1 Rack 2 │ │
│ │ ┌─────┐ ┌─────┐ │ │ ┌─────┐ ┌─────┐ │ │
│ │ │Node1│ │Node2│ │ │ │Node4│ │Node5│ │ │
│ │ │Rep1 │ │Rep2 │ │ │ │Rep4 │ │Rep5 │ │ │
│ │ └─────┘ └─────┘ │ │ └─────┘ └─────┘ │ │
│ │ ┌─────┐ ┌─────┐ │ │ ┌─────┐ ┌─────┐ │ │
│ │ │Node3│ │ │ │ │ │Node6│ │ │ │ │
│ │ │Rep3 │ │ │ │ │ │Rep6 │ │ │ │ │
│ │ └─────┘ └─────┘ │ │ └─────┘ └─────┘ │ │
│ └─────────────────────┘ └─────────────────────┘ │
│ │
│ 副本均匀分布在不同机架 │
│ │
└─────────────────────────────────────────────────────────┘
4.2 创建键空间 #
sql
-- 单数据中心
CREATE KEYSPACE my_keyspace
WITH replication = {
'class': 'NetworkTopologyStrategy',
'datacenter1': 3
};
-- 多数据中心
CREATE KEYSPACE global_keyspace
WITH replication = {
'class': 'NetworkTopologyStrategy',
'dc1': 3, -- 数据中心1,3个副本
'dc2': 2 -- 数据中心2,2个副本
};
-- 多数据中心,不同复制因子
CREATE KEYSPACE production_keyspace
WITH replication = {
'class': 'NetworkTopologyStrategy',
'us-east': 3,
'us-west': 3,
'eu-west': 2
};
4.3 副本放置规则 #
text
NetworkTopologyStrategy副本放置:
┌─────────────────────────────────────────────────────────┐
│ │
│ 规则: │
│ 1. 每个数据中心独立计算副本分布 │
│ 2. 副本优先放置在不同机架 │
│ 3. 尽量均匀分布 │
│ │
│ 示例:DC1配置RF=3,有2个机架 │
│ ├── Rack 1: Node A, Node C │
│ └── Rack 2: Node B, Node D │
│ │
│ 副本分布: │
│ ├── 第1个副本:Rack 1, Node A │
│ ├── 第2个副本:Rack 2, Node B │
│ └── 第3个副本:Rack 1, Node C │
│ │
└─────────────────────────────────────────────────────────┘
4.4 配置数据中心名称 #
yaml
# scylla.yaml配置
endpoint_snitch: GossipingPropertyFileSnitch
# cassandra-rackdc.properties
dc=dc1
rack=rack1
bash
# 查看数据中心信息
nodetool status
# 输出示例
Datacenter: dc1
===============
Status=Up/Down
|/ State=Normal/Leaving/Joining/Moving
-- Address Load Tokens Owns Host ID Rack
UN 192.168.1.1 100 GB 256 33.3% uuid1 rack1
UN 192.168.1.2 100 GB 256 33.3% uuid2 rack2
UN 192.168.1.3 100 GB 256 33.3% uuid3 rack1
Datacenter: dc2
===============
UN 192.168.2.1 100 GB 256 33.3% uuid4 rack1
UN 192.168.2.2 100 GB 256 33.3% uuid5 rack2
五、策略选择 #
5.1 选择指南 #
| 场景 | 推荐策略 | 原因 |
|---|---|---|
| 开发测试 | SimpleStrategy | 配置简单 |
| 单数据中心生产 | NetworkTopologyStrategy | 考虑机架拓扑 |
| 多数据中心 | NetworkTopologyStrategy | 必须使用 |
| 混合云 | NetworkTopologyStrategy | 跨云部署 |
5.2 策略对比 #
| 特性 | SimpleStrategy | NetworkTopologyStrategy |
|---|---|---|
| 配置复杂度 | 简单 | 中等 |
| 数据中心支持 | 单数据中心 | 多数据中心 |
| 机架感知 | 无 | 有 |
| 容灾能力 | 低 | 高 |
| 生产推荐 | 不推荐 | 推荐 |
六、修改复制策略 #
6.1 修改复制因子 #
sql
-- 增加复制因子
ALTER KEYSPACE my_keyspace
WITH replication = {
'class': 'NetworkTopologyStrategy',
'dc1': 5
};
-- 减少复制因子
ALTER KEYSPACE my_keyspace
WITH replication = {
'class': 'NetworkTopologyStrategy',
'dc1': 3
};
6.2 修改后需要修复 #
bash
# 增加复制因子后需要修复
nodetool repair my_keyspace
# 查看修复进度
nodetool repair -pr my_keyspace
6.3 切换策略 #
sql
-- 从SimpleStrategy切换到NetworkTopologyStrategy
ALTER KEYSPACE my_keyspace
WITH replication = {
'class': 'NetworkTopologyStrategy',
'datacenter1': 3
};
-- 切换后需要修复
-- nodetool repair my_keyspace
七、副本读取 #
7.1 一致性级别与副本 #
text
一致性级别与副本关系:
┌─────────────────────────────────────────────────────────┐
│ │
│ RF=3 场景: │
│ │
│ ONE: 读取1个副本 │
│ ┌─────┐ │
│ │Rep 1│ ◀── 读取 │
│ └─────┘ │
│ │
│ QUORUM: 读取2个副本 (RF/2 + 1 = 2) │
│ ┌─────┐ ┌─────┐ │
│ │Rep 1│ │Rep 2│ ◀── 读取 │
│ └─────┘ └─────┘ │
│ │
│ ALL: 读取所有副本 │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Rep 1│ │Rep 2│ │Rep 3│ ◀── 读取 │
│ └─────┘ └─────┘ └─────┘ │
│ │
└─────────────────────────────────────────────────────────┘
7.2 读取示例 #
sql
-- 设置一致性级别
CONSISTENCY QUORUM;
-- 查询
SELECT * FROM users WHERE user_id = uuid();
-- 在驱动中设置
python
from cassandra import ConsistencyLevel
from cassandra.query import SimpleStatement
# 设置查询一致性
query = SimpleStatement("SELECT * FROM users WHERE user_id = %s")
query.consistency_level = ConsistencyLevel.QUORUM
result = session.execute(query, (user_id,))
八、副本写入 #
8.1 写入一致性 #
text
写入一致性级别:
┌─────────────────────────────────────────────────────────┐
│ │
│ RF=3 场景: │
│ │
│ ONE: 写入1个副本确认 │
│ ┌─────┐ │
│ │Rep 1│ ◀── 写入确认 │
│ └─────┘ │
│ 其他副本异步复制 │
│ │
│ QUORUM: 写入2个副本确认 (RF/2 + 1 = 2) │
│ ┌─────┐ ┌─────┐ │
│ │Rep 1│ │Rep 2│ ◀── 写入确认 │
│ └─────┘ └─────┘ │
│ │
│ ALL: 写入所有副本确认 │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Rep 1│ │Rep 2│ │Rep 3│ ◀── 写入确认 │
│ └─────┘ └─────┘ └─────┘ │
│ │
└─────────────────────────────────────────────────────────┘
8.2 写入示例 #
python
from cassandra import ConsistencyLevel
from cassandra.query import SimpleStatement
# 设置写入一致性
insert = SimpleStatement(
"INSERT INTO users (user_id, name) VALUES (%s, %s)"
)
insert.consistency_level = ConsistencyLevel.QUORUM
session.execute(insert, (uuid(), '张三'))
九、副本同步 #
9.1 Hinted Handoff #
text
Hinted Handoff机制:
┌─────────────────────────────────────────────────────────┐
│ │
│ 正常写入: │
│ Client ──▶ Node A (Replica 1) ✓ │
│ ──▶ Node B (Replica 2) ✓ │
│ ──▶ Node C (Replica 3) ✓ │
│ │
│ Node C 故障时: │
│ Client ──▶ Node A (Replica 1) ✓ │
│ ──▶ Node B (Replica 2) ✓ │
│ ──▶ Node C (Replica 3) ✗ │
│ │ │
│ ▼ │
│ Node B 存储 Hint │
│ 等待 Node C 恢复后传递 │
│ │
└─────────────────────────────────────────────────────────┘
9.2 Read Repair #
text
Read Repair机制:
┌─────────────────────────────────────────────────────────┐
│ │
│ 读取时发现不一致: │
│ │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Node A │ │ Node B │ │ Node C │ │
│ │ v1 │ │ v2 │ │ v1 │ │
│ │ (新) │ │ (旧) │ │ (新) │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │ │ │ │
│ └────────────┴────────────┘ │
│ │ │
│ ▼ │
│ 比较版本 │
│ 修复旧数据 │
│ │
└─────────────────────────────────────────────────────────┘
十、最佳实践 #
10.1 复制因子建议 #
| 场景 | RF建议 | 说明 |
|---|---|---|
| 开发环境 | 1 | 节省资源 |
| 测试环境 | 1-2 | 模拟生产 |
| 生产环境 | 3 | 标准配置 |
| 关键业务 | 5 | 高可用 |
10.2 策略配置建议 #
sql
-- 生产环境推荐配置
CREATE KEYSPACE production_ks
WITH replication = {
'class': 'NetworkTopologyStrategy',
'dc1': 3
}
AND durable_writes = true;
-- 多数据中心配置
CREATE KEYSPACE global_ks
WITH replication = {
'class': 'NetworkTopologyStrategy',
'dc1': 3,
'dc2': 3
}
AND durable_writes = true;
十一、总结 #
复制策略要点:
| 策略 | 适用场景 | 特点 |
|---|---|---|
| SimpleStrategy | 单数据中心开发测试 | 简单,不考虑拓扑 |
| NetworkTopologyStrategy | 生产环境 | 考虑拓扑,多数据中心 |
最佳实践:
- 生产环境使用NetworkTopologyStrategy
- RF=3是标准配置
- 合理规划数据中心和机架
- 修改复制因子后执行repair
- 监控副本同步状态
下一步,让我们学习一致性级别!
最后更新:2026-03-27