TiDB存储层与计算层架构深度解析:分布式数据库的核心设计

作者:php是最好的2025.11.04 18:12浏览量:1

简介:本文深度解析TiDB存储层与计算层的架构原理,从分布式KV存储、MVCC机制、Raft协议到计算层SQL解析、分布式执行框架,揭示其作为HTAP数据库的核心设计逻辑。

TiDB存储层与计算层架构深度解析:分布式数据库的核心设计

一、TiDB存储层架构:分布式KV存储的核心设计

1.1 存储层整体架构

TiDB的存储层采用分层架构设计,由TiKV(分布式Key-Value存储引擎)和TiFlash(列式存储引擎)共同构成。TiKV作为默认存储引擎,基于RocksDB实现本地存储,并通过Raft协议实现多副本数据一致性;TiFlash则通过异步复制机制提供列式存储能力,支持实时分析查询。

关键组件

  • Region:TiKV将数据按Key范围划分为多个Region(默认大小96MB),每个Region包含多个副本。
  • Raft Group:每个Region的副本构成一个Raft Group,通过Raft协议保证数据强一致性。
  • PD(Placement Driver):全局调度中心,负责Region的分配、负载均衡和故障恢复。

1.2 MVCC与事务实现

TiDB采用多版本并发控制(MVCC)机制,通过为每个数据版本分配唯一的时间戳(Timestamp)实现读写分离。事务提交时,TiDB会生成全局唯一的事务ID(StartTS和CommitTS),写入操作会生成新版本数据,读取操作则根据事务时间戳读取可见版本。

实现细节

  • 数据版本结构:每个Key对应多个版本,版本信息存储在Value中,包含StartTS、CommitTS和实际数据。
  • GC机制:定期清理过期版本数据,避免存储膨胀。GC通过PD调度执行,默认保留最近10分钟的数据版本。
  • 乐观事务模型:TiDB默认采用乐观事务,冲突检测在提交阶段完成。若检测到冲突,客户端需重试事务。

代码示例(事务提交流程)

  1. // 伪代码:TiDB事务提交流程
  2. func CommitTransaction(txn *Transaction) error {
  3. startTS := txn.StartTS
  4. commitTS := pd.GetTimestamp() // 从PD获取全局唯一时间戳
  5. // 预写日志(WAL)
  6. if err := txn.WriteToWAL(startTS, commitTS); err != nil {
  7. return err
  8. }
  9. // 通过Raft协议提交数据
  10. for _, region := range txn.Regions {
  11. if err := region.ProposeRaftCommand(commitTS, txn.Data); err != nil {
  12. return err
  13. }
  14. }
  15. // 等待Raft提交并应用日志
  16. if err := txn.WaitForCommit(); err != nil {
  17. return err
  18. }
  19. return nil
  20. }

1.3 Raft协议与数据一致性

TiKV通过Raft协议实现多副本数据一致性。每个Region的副本分为Leader、Follower和Learner角色,Leader负责处理写请求,Follower通过复制日志保持数据同步。

关键机制

  • 日志复制:Leader收到写请求后,先写入本地WAL,再通过Raft协议将日志复制到多数派Follower。
  • 选举机制:当Leader故障时,Follower通过超时触发选举,成为新Leader。
  • 联合共识(Joint Consensus):在Region迁移或副本调整时,通过联合共识机制保证数据不丢失。

二、TiDB计算层架构:SQL解析与分布式执行

2.1 计算层整体架构

TiDB的计算层由TiDB Server组成,负责SQL解析、优化和分布式执行。TiDB Server是无状态的,可水平扩展,通过与TiKV和TiFlash交互完成数据读写。

关键组件

  • SQL Parser:将SQL语句解析为抽象语法树(AST)。
  • Logical Plan:将AST转换为逻辑执行计划。
  • Physical Plan:将逻辑计划转换为物理执行计划,考虑数据分布和执行成本。
  • Distributed Execution Framework:将物理计划拆分为可并行执行的任务,分发到不同TiDB Server执行。

2.2 SQL解析与优化

TiDB的SQL解析流程分为词法分析、语法分析和语义分析三个阶段。解析完成后,优化器会生成多种执行计划,并通过代价模型选择最优计划。

优化策略

  • 统计信息收集:定期收集表和索引的统计信息(如行数、Distinct值),用于代价估算。
  • 索引选择:基于统计信息选择最优索引,避免全表扫描。
  • 子查询优化:将子查询转换为Join或半连接(Semi-Join),减少计算开销。
  • 分布式Join优化:根据数据分布选择Broadcast Join、Shuffle Join或Index Join。

代码示例(执行计划生成)

  1. // 伪代码:TiDB执行计划生成
  2. func GeneratePlan(sql string) (*PhysicalPlan, error) {
  3. // 1. SQL解析
  4. ast, err := parser.Parse(sql)
  5. if err != nil {
  6. return nil, err
  7. }
  8. // 2. 逻辑优化
  9. logicalPlan := optimizer.OptimizeLogical(ast)
  10. // 3. 物理优化
  11. physicalPlan := optimizer.OptimizePhysical(logicalPlan)
  12. // 4. 分布式任务拆分
  13. tasks := distExecutor.SplitTasks(physicalPlan)
  14. return physicalPlan, nil
  15. }

2.3 分布式执行框架

TiDB的分布式执行框架通过Volcano模型实现,将物理计划拆分为多个算子(Operator),每个算子可并行执行。执行过程中,数据通过RPC在TiDB Server之间流动。

关键机制

  • 数据分片:根据Region分布将数据划分为多个分片,每个分片由一个TiDB Server处理。
  • 流水线执行:算子之间通过管道(Pipeline)传递数据,减少内存占用。
  • 故障恢复:通过检查点(Checkpoint)机制记录执行进度,故障时从检查点恢复。

三、存储层与计算层的协同:HTAP实现

3.1 HTAP架构设计

TiDB通过行存(TiKV)+列存(TiFlash)的混合架构实现HTAP。TiKV负责事务型负载,TiFlash通过异步复制提供列式存储能力,支持实时分析查询。

协同机制

  • 一致性保证:TiFlash通过Raft Listener监听TiKV的Raft日志,保证与TiKV的数据一致性。
  • 智能路由:执行计划根据查询类型自动选择存储引擎,OLTP查询路由到TiKV,OLAP查询路由到TiFlash。
  • 向量化执行:TiFlash支持向量化执行引擎,提升分析查询性能。

3.2 实际应用建议

  1. 事务型负载优化

    • 合理设计主键,避免热点问题。
    • 使用乐观事务时,控制事务大小,减少冲突概率。
    • 定期执行ANALYZE TABLE更新统计信息。
  2. 分析型负载优化

    • 为分析查询创建TiFlash副本。
    • 使用COLLATEFILTER优化列存查询。
    • 避免在分析查询中使用事务。
  3. 监控与调优

    • 通过Prometheus和Grafana监控TiDB和TiKV的指标。
    • 根据PD的调度信息调整Region分布。
    • 使用TIDB_SLOW_QUERY表定位慢查询。

四、总结与展望

TiDB的存储层与计算层通过分布式KV存储、MVCC机制、Raft协议和分布式SQL执行框架实现了高性能、高可用的HTAP数据库。未来,TiDB将继续优化存储层的数据压缩和计算层的向量化执行,同时探索AI与数据库的深度融合,为用户提供更智能的数据库服务。