05.TiDB分布式一致性常识原理
TiDB 采用 Percolator 模型,通过 MVCC 和 2PC 实现分布式事务的高效一致性
每个事务通过 PD 分配的时间戳控制可见性与一致性,确保跨节点数据的原子性
事务执行分为准备和提交阶段,通过 Prewrite 和 Commit 处理读写,避免锁争用
与 MySQL 单机事务模型不同,TiDB 适用于大规模分布式场景,支持全局时间戳和快照读,提升了并发和读写性能
# 01.背景说明
# 1、概述
- TiDB 通过采用 Percolator 模型结合 MVCC 和 2PC 实现了分布式事务的高效一致性
- 该模型通过时间戳控制读写并发,保证了每个事务能看到一致的数据库状态
- 同时通过二阶段提交保证了跨多个 TiKV 节点的数据原子性和一致性
- 与 MySQL 传统的单机事务模型相比,TiDB 更适合分布式、大规模高并发场景,实现了分布式环境下的事务一致性和高性能
# 2、背景与挑战
在分布式数据库中,事务操作通常会跨越多个节点
而事务的一致性要求确保每个节点的数据修改都必须符合
ACID(Atomicity、Consistency、Isolation、Durability)属性,尤其是原子性和一致性
实现分布式事务时,最大挑战在于如何保证事务操作在不同存储节点上的一致性,同时避免性能瓶颈
Percolator 模型针对分布式场景,提供了一种轻量级、高并发的事务管理机制,解决了以下问题
- 跨节点数据一致性:通过
分布式锁机制
和二阶段提交
保证分布式事务的一致性
- 高并发与低延迟:通过
MVCC 和乐观并发控制
减少锁争用,提升并发度和读写性能
# 02.Percolator TiDB 实现
- Percolator 模型的核心机制是基于 2PC(二阶段提交) 实现的
- 每个事务的执行过程分为两个阶段:
准备阶段
和提交阶段
# 1、事务的时间戳(TSO)
- TiDB 中的每个事务会分配一个全局唯一的时间戳,这个时间戳由 PD(Placement Driver)生成,用来标识事务的逻辑时间顺序
- 时间戳不仅用于控制事务的可见性(MVCC),还用于在二阶段提交中协调不同节点之间的数据一致性
# 2、二阶段提交(2PC)
- 二阶段提交(2PC)是分布式事务模型的关键组成部分,确保跨多个 TiKV 节点的事务可以一致提交或一致回滚
# 1)第一阶段:Prepare 阶段
开始事务:事务开始时,客户端向 PD 请求分配一个全局唯一的时间戳,称为
StartTS
,作为当前事务的起始时间锁定资源:
事务要修改的数据分布在多个 TiKV 节点上在第一阶段,事务会在这些节点上对所有需要修改的 key 加锁,这种锁称为 悲观锁 或 乐观锁,具体视事务模式而定
- 每个 key 的锁都会记录当前事务的
StartTS
,以确保其他事务无法在该 key 上并发写入
- 每个 key 的锁都会记录当前事务的
写入 Prewrite:
- 在锁定数据后,TiKV 会为每个参与的 key 写入一条 Prewrite 记录,其中包含事务的
StartTS
和待提交的新数据版本 - Prewrite 是一种临时数据,它表明该 key 正在被修改,但尚未正式提交
- 在锁定数据后,TiKV 会为每个参与的 key 写入一条 Prewrite 记录,其中包含事务的
# 2)第二阶段:Commit 阶段
- 提交事务:
- 在所有 key 都成功写入 Prewrite 之后,事务进入提交阶段TiDB 为当前事务请求一个新的时间戳,称为
CommitTS
,作为事务提交的标识 - 提交事务 时,TiDB 将所有 key 的数据从 Prewrite 状态更新为正式提交状态,即写入
CommitTS
并将数据的版本标记为CommitTS
- 在所有 key 都成功写入 Prewrite 之后,事务进入提交阶段TiDB 为当前事务请求一个新的时间戳,称为
- 事务提交成功:
- 一旦所有 key 都成功写入
CommitTS
,事务被认为成功提交,其他事务在读写这些 key 时,将使用CommitTS
对应的版本数据
- 一旦所有 key 都成功写入
- 回滚处理:
- 如果在提交过程中任一阶段出现错误(例如某个 TiKV 节点无法响应),事务会自动进入回滚流程
- 回滚操作 会清除对应 key 的 Prewrite 记录,恢复数据的原始版本,确保数据的一致性
# 3、MVCC 和可见性
在 TiDB 中,每次写操作生成的新版本都会附带时间戳,并存储在 TiKV 中的 RocksDB 引擎中通过 MVCC,每个 key 存储多个版本,旧版本不会被立即覆盖,而是根据时间戳保存下来TiDB 在读取数据时,会根据事务的 StartTS
确定当前事务能够看到哪些数据版本
- 读取操作通过时间戳选择合适的版本,确保事务读取到的数据是一致的,并且不会被并发的写操作干扰
- 由于 MVCC,TiDB 能够支持 快照读,这意味着读取的数据总是某个时间点上的快照,而无需阻塞写操作
# 4、事务隔离级别
TiDB 支持 可重复读(Repeatable Read) 的事务隔离级别这意味着:
- 事务在开始时生成一个
StartTS
,整个事务期间的所有读操作都会基于这个时间戳,保证事务内部的数据一致性 - 当一个事务修改数据时,其他事务无法立即看到这些修改,直到该事务成功提交
与 MySQL 类似,TiDB 通过 MVCC 机制,结合事务的时间戳,实现了类似 快照读 的行为,从而避免了锁的争用
# 5、与MySQ模型对比
- 分布式架构:
- TiDB 基于 Google 的 Percolator 模型,主要解决大规模分布式场景下的事务一致性问题
- 而 MySQL 的传统事务处理主要面向单机环境
- 通过 binlog 和主从复制机制实现容灾和高可用,但在分布式环境下处理跨节点事务时显得力不从心
- 全局时间戳:
- TiDB 依赖于 PD 提供的全局唯一时间戳,保证分布式事务的顺序性和一致性
- MySQL 没有全局时间戳的概念,事务的时间序列性更多依赖于本地的自增 ID 或 binlog
- 事务隔离性:
- TiDB 的 MVCC 和 Percolator 结合使得它天然支持分布式事务的隔离性,并通过快照读避免锁的争用
- MySQL 则依赖于锁机制和 undo log 来保证隔离性,虽然同样支持 MVCC,但其设计主要针对集中式环境