在一致性模型中,线性一致性和顺序一致性的区别是什么

zhidiantech · · 21 次点击 · · 开始浏览    
--- ### **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**:默认线性一致性,适合强一致事务;可通过配置降级一致性以提升性能。
21 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传