---
### **1. 核心区别:是否认“真实时间”的账**
• **线性一致性**:像有个**全球统一的大钟**,所有操作必须按真实发生的先后顺序排队。你做完一个操作(比如存钱),后面所有人立刻能看到最新结果,不存在“我刚刚存的100块,别人却查不到”的情况。
*举例*:你去银行存钱,柜员A操作完,下一秒柜员B查余额必须显示刚存的钱。
• **顺序一致性(zookeeper)**:不认真实时间,只要**大家编的故事一致**就行。比如你存钱和同事取钱同时发生,只要所有人最终都认同“先存后取”或“先取后存”的顺序,就算符合规则,哪怕实际时间上两人操作是重叠的。
*举例*:你和同事同时操作账户,只要银行记录里你俩的操作顺序一致(比如系统统一说“先处理你的存钱,再处理他的取钱”),哪怕实际是同时发生的,也算合规。
---
### **2. 读数据时看到的“新鲜度”**
• **线性一致性**:**必须读到最新数据**。比如你刚更新了朋友圈,别人刷新立刻能看到,不存在“刷了好几次才刷到”。
• **顺序一致性**:**允许读到旧数据**,但保证多次读的结果不会“时间倒流”。比如你发朋友圈后,别人第一次刷可能看不到,但多刷几次一定能看到,且之后不会变回旧内容。
---
### **3. 实际场景中的表现**
• **线性一致性场景**:股票交易系统。股价变动必须实时反映,所有人看到的都是同一时刻的最新价格,不能有人延迟。
• **顺序一致性场景**:微博热搜榜。榜单更新可能有延迟,但最终所有人看到的榜单顺序一致(比如“某明星结婚”先于“某产品发布”),即使实际这两个事件是同时发生的。
---
### **总结成一句话**
• 线性一致性:**全球统一时间轴,所见即最新**(强实时)。
• 顺序一致性:**大家剧本一致就行,不管真实发生顺序**(弱实时,强顺序)。
示例:
ZooKeeper 和 TiDB 在分布式一致性模型上有显著差异,以下是详细分析:
---
### **一、ZooKeeper 的一致性模型:顺序一致性**
#### **1. 核心特性**
- **顺序一致性(Sequential Consistency)**:
- **全局有序**:所有客户端的操作(读/写)按照一个全局顺序执行。
- **实时性无保证**:读操作可能看到稍旧的数据(如客户端可能读到未更新的副本),但所有客户端观察到的操作顺序一致。
- **实现机制**:
- 基于 **ZAB 协议(ZooKeeper Atomic Broadcast)**,保证事务的全局有序广播。
- 写操作由 Leader 发起,需多数派确认后提交;读操作可直接由任意副本处理(可能读到旧数据)。
#### **2. 示例场景**
- **写操作流程**:
1. 客户端 A 写入 `set /key value1`。
2. Leader 广播事务到所有 Follower,多数派确认后提交。
3. 客户端 B 读取 `/key`,可能由 Follower 响应,可能读到 `value1` 或旧值(取决于副本同步状态)。
- **顺序性保证**:
- 所有客户端看到的操作顺序一致(如 A 的写操作一定在 B 的读操作之前),但读操作不保证实时性。
---
### **二、TiDB 的一致性模型:线性一致性**
#### **1. 核心特性**
- **线性一致性(Linearizability)**:
- **实时有序**:所有操作(读/写)看起来像是原子性地在某个时间点完成。
- **读最新写**:读操作总能读到最新已提交的数据。
- **实现机制**:
- TiKV(TiDB 的存储层)基于 **Raft 协议**,每个 Region 的 Leader 处理读写请求。
- 写操作需同步到多数派副本后才响应客户端;读操作默认由 Leader 处理(直接返回最新数据)。
#### **2. 示例场景**
- **写操作流程**:
1. 客户端 A 写入 `UPDATE table SET col=1 WHERE id=100`。
2. Leader 同步数据到多数派副本,提交后返回成功。
3. 客户端 B 读取 `id=100` 的记录,由 Leader 响应,**立即读到 `col=1`**。
- **线性化保证**:
- 所有读写操作按实际发生的顺序全局可见,无旧数据问题。
---
### **三、对比总结**
| **特性** | **ZooKeeper** | **TiDB** |
|------------------------|--------------------------------|---------------------------------|
| **一致性模型** | 顺序一致性 | 线性一致性(默认) |
| **读操作实时性** | 可能读到旧数据(Follower 读) | 总是读到最新数据(Leader 读) |
| **写操作提交条件** | 多数派确认(ZAB 协议) | 多数派确认(Raft 协议) |
| **适用场景** | 分布式协调(如锁、配置管理) | 强一致事务(如金融交易) |
| **性能与延迟** | 低延迟,适合高频读 | 写延迟较高,适合强一致读写 |
---
### **四、扩展说明**
#### **1. ZooKeeper 的读操作优化**
- **`sync()` 方法**:
调用 `sync()` 后,客户端可强制后续读操作看到最新的数据(近似线性一致性),但需额外开销。
```java
zk.sync(path, (rc, path, ctx) -> {}, null); // 强制同步
zk.getData(path, watch, stat); // 此时读到最新数据
```
#### **2. TiDB 的灵活一致性配置**
- **Follower 读**:
通过设置 `SET tidb_replica_read='follower'`,允许从 Follower 读取数据,此时一致性降为**最终一致性**,但提升读吞吐量。
- **Stale Read**:
指定时间戳读取历史数据(如 `SELECT * FROM t AS OF TIMESTAMP NOW() - 10`),用于分析场景。
---
### **五、总结**
- **ZooKeeper**:顺序一致性,适合协调类场景,读操作可能滞后,但全局有序。
- **TiDB**:默认线性一致性,适合强一致事务;可通过配置降级一致性以提升性能。
上一篇:创建云主机你不知道的那些事
下一篇:批量创建云主机的整个过程
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传