复制策略 #

一、复制概述 #

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 生产环境 考虑拓扑,多数据中心

最佳实践:

  1. 生产环境使用NetworkTopologyStrategy
  2. RF=3是标准配置
  3. 合理规划数据中心和机架
  4. 修改复制因子后执行repair
  5. 监控副本同步状态

下一步,让我们学习一致性级别!

最后更新:2026-03-27