一致性级别 #
一、一致性概述 #
1.1 CAP理论 #
ScyllaDB作为分布式数据库,遵循CAP理论,在一致性和可用性之间进行权衡。
text
CAP理论:
┌─────────────────────────────────────────────────────────┐
│ │
│ CAP 定理 │
│ │
│ Consistency │
│ (C) │
│ /\ │
│ / \ │
│ / \ │
│ / \ │
│ / AP \ │
│ / \ │
│ Availability ──────────────── Partition Tolerance │
│ (A) (P) │
│ │
│ ScyllaDB 选择 AP + 可调一致性 │
│ │
└─────────────────────────────────────────────────────────┘
1.2 一致性级别定义 #
一致性级别决定了读写操作需要多少副本确认才算成功。
text
一致性级别影响:
┌─────────────────────────────────────────────────────────┐
│ │
│ 强一致性(高) │
│ ├── ALL │
│ ├── QUORUM │
│ └── ONE │
│ │
│ 弱一致性(低) │
│ └── ANY │
│ │
│ 强一致性 ←───────────────────────────→ 高可用性 │
│ 低延迟 ←───────────────────────────→ 高延迟 │
│ │
└─────────────────────────────────────────────────────────┘
二、一致性级别类型 #
2.1 读一致性级别 #
| 级别 | 说明 | 副本数 |
|---|---|---|
| ONE | 读取最近的一个副本 | 1 |
| QUORUM | 读取多数副本 | RF/2 + 1 |
| ALL | 读取所有副本 | RF |
| LOCAL_ONE | 读取本地数据中心一个副本 | 1 |
| LOCAL_QUORUM | 读取本地数据中心多数副本 | RF/2 + 1 |
| EACH_QUORUM | 每个数据中心都达到QUORUM | 每DC: RF/2 + 1 |
2.2 写一致性级别 #
| 级别 | 说明 | 副本数 |
|---|---|---|
| ANY | 至少一个节点收到(可以是Hint) | 1 |
| ONE | 至少一个副本确认 | 1 |
| QUORUM | 多数副本确认 | RF/2 + 1 |
| ALL | 所有副本确认 | RF |
| LOCAL_ONE | 本地数据中心一个副本确认 | 1 |
| LOCAL_QUORUM | 本地数据中心多数副本确认 | RF/2 + 1 |
三、一致性级别详解 #
3.1 ONE #
text
ONE 一致性级别:
┌─────────────────────────────────────────────────────────┐
│ │
│ RF=3 场景 │
│ │
│ 写入: │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Node1│ │Node2│ │Node3│ │
│ │ ✓ │ │ │ │ │ │
│ └─────┘ └─────┘ └─────┘ │
│ 只需1个副本确认 │
│ │
│ 读取: │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Node1│ │Node2│ │Node3│ │
│ │ ◀── │ │ │ │ │ │
│ └─────┘ └─────┘ └─────┘ │
│ 只读取1个副本 │
│ │
│ 特点:低延迟,弱一致性 │
│ │
└─────────────────────────────────────────────────────────┘
python
# Python示例
from cassandra import ConsistencyLevel
from cassandra.query import SimpleStatement
# 设置ONE一致性
statement = SimpleStatement("SELECT * FROM users WHERE user_id = %s")
statement.consistency_level = ConsistencyLevel.ONE
3.2 QUORUM #
text
QUORUM 一致性级别:
┌─────────────────────────────────────────────────────────┐
│ │
│ RF=3 场景,QUORUM = 2 (3/2 + 1) │
│ │
│ 写入: │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Node1│ │Node2│ │Node3│ │
│ │ ✓ │ │ ✓ │ │ │ │
│ └─────┘ └─────┘ └─────┘ │
│ 需要2个副本确认 │
│ │
│ 读取: │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Node1│ │Node2│ │Node3│ │
│ │ ◀── │ │ ◀── │ │ │ │
│ └─────┘ └─────┘ └─────┘ │
│ 读取2个副本,比较版本 │
│ │
│ 特点:平衡一致性和性能 │
│ │
└─────────────────────────────────────────────────────────┘
sql
-- cqlsh中设置
CONSISTENCY QUORUM;
-- 查询
SELECT * FROM users WHERE user_id = uuid();
3.3 ALL #
text
ALL 一致性级别:
┌─────────────────────────────────────────────────────────┐
│ │
│ RF=3 场景 │
│ │
│ 写入: │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Node1│ │Node2│ │Node3│ │
│ │ ✓ │ │ ✓ │ │ ✓ │ │
│ └─────┘ └─────┘ └─────┘ │
│ 所有副本必须确认 │
│ │
│ 读取: │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Node1│ │Node2│ │Node3│ │
│ │ ◀── │ │ ◀── │ │ ◀── │ │
│ └─────┘ └─────┘ └─────┘ │
│ 读取所有副本 │
│ │
│ 特点:强一致性,任一节点故障则失败 │
│ │
└─────────────────────────────────────────────────────────┘
3.4 LOCAL_QUORUM #
text
LOCAL_QUORUM 一致性级别:
┌─────────────────────────────────────────────────────────┐
│ │
│ 多数据中心场景 │
│ │
│ Datacenter 1 Datacenter 2 │
│ ┌───────────────┐ ┌───────────────┐ │
│ │ Node1 Node2 │ │ Node4 Node5 │ │
│ │ ✓ ✓ │ │ │ │
│ │ Node3 │ │ Node6 │ │
│ └───────────────┘ └───────────────┘ │
│ ↑ │
│ 本地DC达到QUORUM │
│ │
│ 特点:本地强一致,跨DC低延迟 │
│ │
└─────────────────────────────────────────────────────────┘
python
# 多数据中心推荐配置
from cassandra import ConsistencyLevel
# 写入使用LOCAL_QUORUM
insert = SimpleStatement("INSERT INTO users ...")
insert.consistency_level = ConsistencyLevel.LOCAL_QUORUM
# 读取使用LOCAL_QUORUM
select = SimpleStatement("SELECT * FROM users ...")
select.consistency_level = ConsistencyLevel.LOCAL_QUORUM
3.5 ANY #
text
ANY 一致性级别:
┌─────────────────────────────────────────────────────────┐
│ │
│ 仅用于写入 │
│ │
│ 场景:所有副本节点都不可用 │
│ │
│ ┌─────┐ ┌─────┐ ┌─────┐ │
│ │Node1│ │Node2│ │Node3│ │
│ │ ✗ │ │ ✗ │ │ ✗ │ │
│ └─────┘ └─────┘ └─────┘ │
│ │
│ 协调节点存储Hint │
│ ┌─────────────┐ │
│ │ Coordinator │ │
│ │ Hint │ ◀── 存储写入 │
│ └─────────────┘ │
│ │
│ 特点:最高可用性,最低一致性 │
│ │
└─────────────────────────────────────────────────────────┘
四、一致性级别选择 #
4.1 选择矩阵 #
| 场景 | 读一致性 | 写一致性 | 说明 |
|---|---|---|---|
| 高可用 | ONE | ONE | 牺牲一致性 |
| 平衡 | QUORUM | QUORUM | 推荐配置 |
| 强一致 | ALL | ALL | 牺牲可用性 |
| 多DC | LOCAL_QUORUM | LOCAL_QUORUM | 本地一致 |
| 关键数据 | QUORUM | ALL | 写入强一致 |
4.2 QUORUM计算 #
text
QUORUM计算公式:
┌─────────────────────────────────────────────────────────┐
│ │
│ QUORUM = floor(RF / 2) + 1 │
│ │
│ RF=1: QUORUM = 1 │
│ RF=2: QUORUM = 2 │
│ RF=3: QUORUM = 2 │
│ RF=5: QUORUM = 3 │
│ │
│ 读写都使用QUORUM可保证强一致性: │
│ R + W > RF │
│ 2 + 2 > 3 ✓ │
│ │
└─────────────────────────────────────────────────────────┘
4.3 一致性权衡 #
text
一致性 vs 可用性 vs 性能:
┌─────────────────────────────────────────────────────────┐
│ │
│ 强一致性 (ALL) │
│ ├── 优点:数据强一致 │
│ ├── 缺点:任一节点故障则失败 │
│ └── 延迟:最高 │
│ │
│ 平衡 (QUORUM) │
│ ├── 优点:一致性和可用性平衡 │
│ ├── 缺点:需要多数节点 │
│ └── 延迟:中等 │
│ │
│ 高可用 (ONE/ANY) │
│ ├── 优点:高可用,低延迟 │
│ ├── 缺点:可能读到旧数据 │
│ └── 延迟:最低 │
│ │
└─────────────────────────────────────────────────────────┘
五、实际应用示例 #
5.1 金融交易 #
python
# 金融交易:强一致性
from cassandra import ConsistencyLevel
from cassandra.query import SimpleStatement
# 写入交易记录
insert_trade = SimpleStatement("""
INSERT INTO trades (trade_id, account_id, amount, timestamp)
VALUES (?, ?, ?, ?)
""")
insert_trade.consistency_level = ConsistencyLevel.QUORUM
# 查询账户余额
get_balance = SimpleStatement("""
SELECT balance FROM accounts WHERE account_id = ?
""")
get_balance.consistency_level = ConsistencyLevel.QUORUM
5.2 社交媒体 #
python
# 社交媒体:高可用性
# 写入帖子
insert_post = SimpleStatement("""
INSERT INTO posts (post_id, user_id, content, timestamp)
VALUES (?, ?, ?, ?)
""")
insert_post.consistency_level = ConsistencyLevel.ONE
# 读取时间线
get_timeline = SimpleStatement("""
SELECT * FROM timeline WHERE user_id = ?
""")
get_timeline.consistency_level = ConsistencyLevel.ONE
5.3 物联网数据 #
python
# 物联网:高吞吐,低延迟
# 写入传感器数据
insert_sensor = SimpleStatement("""
INSERT INTO sensor_data (device_id, timestamp, value)
VALUES (?, ?, ?)
""")
insert_sensor.consistency_level = ConsistencyLevel.ONE
# 查询最新数据
get_latest = SimpleStatement("""
SELECT * FROM sensor_data
WHERE device_id = ?
ORDER BY timestamp DESC
LIMIT 100
""")
get_latest.consistency_level = ConsistencyLevel.ONE
5.4 多数据中心应用 #
python
# 多数据中心配置
from cassandra.cluster import Cluster
from cassandra.policies import DCAwareRoundRobinPolicy
# 连接本地数据中心
cluster = Cluster(
['192.168.1.1'],
load_balancing_policy=DCAwareRoundRobinPolicy(
local_dc='dc1'
)
)
session = cluster.connect()
# 使用LOCAL_QUORUM
query = SimpleStatement("SELECT * FROM users WHERE user_id = ?")
query.consistency_level = ConsistencyLevel.LOCAL_QUORUM
六、一致性级别设置 #
6.1 cqlsh设置 #
sql
-- 查看当前一致性级别
CONSISTENCY;
-- 设置一致性级别
CONSISTENCY QUORUM;
-- 设置为LOCAL_QUORUM
CONSISTENCY LOCAL_QUORUM;
6.2 Python驱动设置 #
python
from cassandra import ConsistencyLevel
from cassandra.cluster import Cluster
from cassandra.query import SimpleStatement
cluster = Cluster(['localhost'])
session = cluster.connect()
# 单条语句设置
statement = SimpleStatement("SELECT * FROM users")
statement.consistency_level = ConsistencyLevel.QUORUM
# 全局默认设置
from cassandra.policies import ConsistencyLevel
cluster = Cluster(
['localhost'],
default_consistency_level=ConsistencyLevel.LOCAL_QUORUM
)
6.3 Java驱动设置 #
java
import com.datastax.oss.driver.api.core.CqlSession;
import com.datastax.oss.driver.api.core.config.DriverConfigLoader;
import com.datastax.oss.driver.api.core.ConsistencyLevel;
// 配置文件方式
DriverConfigLoader loader = DriverConfigLoader.fromClasspath("application.conf");
// 代码方式
CqlSession session = CqlSession.builder()
.addContactPoint(new InetSocketAddress("localhost", 9042))
.withLocalDatacenter("datacenter1")
.build();
SimpleStatement statement = SimpleStatement.builder("SELECT * FROM users")
.setConsistencyLevel(ConsistencyLevel.QUORUM)
.build();
七、一致性保证机制 #
7.1 Read Repair #
sql
-- Read Repair在读取时自动触发
-- 比较多个副本,修复不一致数据
-- 设置read_repair_chance
ALTER TABLE users
WITH read_repair_chance = 0.1; -- 10%概率触发
-- 或禁用后台read repair
ALTER TABLE users
WITH read_repair_chance = 0.0;
7.2 写后读一致性 #
python
# 写后读一致性保证
# 写入使用QUORUM,读取使用QUORUM
# R + W > RF 保证能读到最新写入
def write_and_read_example():
# 写入
insert = SimpleStatement(
"INSERT INTO users (user_id, name) VALUES (?, ?)"
)
insert.consistency_level = ConsistencyLevel.QUORUM
session.execute(insert, (user_id, '张三'))
# 读取
select = SimpleStatement(
"SELECT * FROM users WHERE user_id = ?"
)
select.consistency_level = ConsistencyLevel.QUORUM
result = session.execute(select, (user_id,))
# 保证能读到最新数据
八、最佳实践 #
8.1 推荐配置 #
| 场景 | 读 | 写 | 说明 |
|---|---|---|---|
| 默认配置 | LOCAL_QUORUM | LOCAL_QUORUM | 推荐 |
| 高吞吐 | ONE | ONE | 牺牲一致性 |
| 关键数据 | QUORUM | ALL | 强一致写入 |
| 多DC | LOCAL_QUORUM | EACH_QUORUM | 跨DC强一致 |
8.2 决策指南 #
text
一致性级别决策流程:
┌─────────────────────────────────────────────────────────┐
│ │
│ 1. 是否多数据中心? │
│ ├── 是 → 使用 LOCAL_QUORUM │
│ └── 否 → 继续 │
│ │
│ 2. 数据是否关键? │
│ ├── 是 → 使用 QUORUM │
│ └── 否 → 继续 │
│ │
│ 3. 是否需要高吞吐? │
│ ├── 是 → 使用 ONE │
│ └── 否 → 使用 QUORUM │
│ │
└─────────────────────────────────────────────────────────┘
九、总结 #
一致性级别要点:
| 级别 | 一致性 | 可用性 | 延迟 |
|---|---|---|---|
| ALL | 最高 | 最低 | 最高 |
| QUORUM | 高 | 中 | 中 |
| ONE | 低 | 高 | 低 |
| ANY | 最低 | 最高 | 最低 |
最佳实践:
- 默认使用QUORUM
- 多DC使用LOCAL_QUORUM
- 关键数据使用更高一致性
- 监控一致性相关指标
- 理解业务需求后选择
下一步,让我们学习键空间操作!
最后更新:2026-03-27