03.TiDB存储引擎与Raft常识原理
TiKV 通过 Raft 协议实现强一致性和多副本存储,确保集群在节点故障时仍然保持数据一致性和高可用性
每个 Region 维护 3 副本,由 Raft Group 管理,所有写操作需通过 Leader 执行并复制到 Follower 节点
Raft 协议支持 Leader 选举、日志复制和故障恢复,PD 负责 Region 分配、负载均衡与调度
即使部分节点宕机,副本冗余机制保障系统的容错性与动态扩容能力
# 01.TiDB 存储引擎与 Raft 协议
- 通过 Raft 协议,TiKV 实现了强一致性的多副本存储和容错机制
- 这种设计保证了 TiDB 集群在面对部分节点故障时依然能够保持数据一致性和高可用性
- 同时支持动态扩容和副本调度,极大地提升了系统的稳定性和可扩展性
# 1、TiKV 的副本机制与 Raft
TiKV 是 TiDB 集群的分布式存储引擎,每一个数据块 (Region) 都会维护多副本(通常是 3 副本)
这些副本分布在不同的 TiKV 实例上,形成一个 Raft Group
- Raft Group:
- 每个 Region 的数据有 3 个副本,这 3 个副本会组成一个 Raft Group,每个副本对应一个 Raft Node
- Raft Group 中的副本有一个 Leader 和多个 Follower,所有的写操作和读取操作都必须经过 Leader
- Leader Election(选举):
- Raft 协议通过心跳机制保证 Leader 的存在
- 如果 Leader 挂掉,剩下的 Follower 会发起选举,选择出一个新的 Leader 来继续负责处理读写请求
# 2、Raft 的工作原理
Raft 是一种强一致性协议,它的核心思想是通过日志复制 (Log Replication) 来保持数据一致性,并通过选举机制来保证系统的容错性
TiKV 使用 Raft 实现以下几项核心功能
- Leader 选举:
- Raft 中,每个 Region 的 Raft Group 都有一个 Leader,Leader 负责处理客户端的所有写入请求
- 当 Leader 挂掉时,Raft Group 的 Follower 节点通过选举机制选出一个新的 Leader
- 日志复制:
- 所有写入操作必须通过 Raft Leader 来进行
- Leader 将写入操作以日志的形式复制到所有 Follower 节点,确保所有副本都拥有相同的日志顺序
- 在大多数 Follower 返回确认后,Leader 会将数据持久化,并返回成功
- 数据一致性保证:
- Raft 协议通过多数派的原则(Quorum,通常是 N/2 + 1 个节点)来保证一致性
- 即使部分节点(不超过副本总数的一半)发生故障,系统仍然能够保证数据一致性
- 数据恢复:
- 如果某个副本丢失或崩溃,新的 Leader 会将缺失的数据重新复制到该副本中,以确保所有副本的一致性
# 3、TiKV 中的 Raft 多副本机制
- 在 TiKV 中,Region 是数据的最小分片单位
- 每个 Region 的数据通过 Raft 协议维护 3 个副本,分布在不同的 TiKV 实例上,以确保数据的高可用性和一致性
# 1)写入流程
- 客户端
发起写请求
,TiDB Server 将请求转发给相应的 TiKV Leader
- TiKV Leader 将
写请求打包成 Raft 日志
,并将其发送给 Raft Group 中的 Follower 节点
- 一旦
Raft Group 中的大多数节点
(通常是 Leader + 至少一个 Follower)成功写入日志
,Leader 将确认该请求,并将最终数据持久化 - TiKV Leader 向 TiDB Server 返回写入成功的响应,TiDB Server 最终返回给客户端
# 2)读请求
- TiKV 的读取请求默认是从 Leader 节点读取,以确保读取的数据始终是一致的
- 不过在某些场景下,TiKV 也支持从 Follower 读取(通过
ReadIndex
来保证读取数据的一致性)
# 3)故障恢复
- Leader 故障:
- 当 Leader 节点故障时,Raft Group 中的 Follower 会检测到 Leader 的心跳中断,并发起选举
- 在大多数节点投票后,新的 Leader 会被选举出来并继续处理客户端请求
- Follower 故障:
- 如果某个 Follower 节点发生故障,Leader 会继续向其余的 Follower 节点复制日志
- 待故障节点恢复后,Leader 会自动将缺失的日志补齐
# 4、管理 Region 分配与调度
- PD (Placement Driver) 在 TiDB 集群中扮演着数据分布和调度的角色
- 负责管理每个 Region 的 Raft Group 和副本的分布
- Region 切分与合并:
- TiKV 中的每个 Region 都有一个固定的大小(默认 96MB)
- 当一个 Region 的数据量达到上限时,PD 会触发 Region 的分裂操作,将其分为两个较小的 Region
- 反之,如果多个相邻 Region 数据较少,PD 可能会触发 Region 的合并操作
- 副本调度与负载均衡:
- PD 负责监控 TiKV 集群的负载情况,并根据副本的状态和集群的整体健康情况,动态调度副本
- 例如,当某个 TiKV 节点的负载过高时,PD 会将部分 Region 的副本迁移到负载较低的节点上,从而实现负载均衡
# 5、Raft 的高可用性与容错性
- 由于 Raft 协议通过副本冗余和多数派原则实现容错机制
- 因此 TiKV 集群即使出现部分节点宕机或网络分区,依然可以提供强一致性的服务
- 副本冗余:
- 即使一个副本出现故障,另外两个副本依然可以通过 Leader 和 Follower 协同工作,保证数据一致性和可用性
- 动态扩展与收缩:
- TiKV 支持在线扩容和缩容
- 当需要增加节点时,PD 会自动调整 Region 的副本分布,并将新的 TiKV 节点纳入集群
- 当某个节点失效时,PD 会重新调度副本,确保数据在集群中的可用性
# 6、写入 Raft 工作流程
假设我们在 orders
表中插入一条新订单数据 user_id = 12345, order_id = 67890
- 客户端请求:客户端向 TiDB Server 发起写入请求
INSERT INTO orders (user_id, order_id) VALUES (12345, 67890);
- TiDB Server 处理:TiDB Server 将 SQL 解析为相应的 Key-Value 数据,并确定需要写入
orders_table+order_id
的 Key - TiKV Leader 写入:TiDB Server 将请求转发给对应的 TiKV Leader,Leader 将写操作记录为 Raft 日志,并将日志同步到 Follower 节点
- Raft 日志复制:Leader 等待至少一个 Follower 返回确认(多数派原则),然后将数据持久化
- 响应客户端:Leader 将写入成功的结果返回给 TiDB Server,TiDB Server 最终返回给客户端
通过这一过程,TiKV 通过 Raft 实现了数据的多副本冗余和高可用性即使某个 TiKV 节点故障,系统依然能够通过剩余副本确保数据的一致性和完整性
上次更新: 2024/10/15 16:27:13