02.TiDB架构原理 ✅常识原理
TiDB通过无状态的TiDB Server处理SQL查询请求,将关系型数据转换为键值对存储在分布式的TiKV中
架构中各个组件协同工作
- TiDB Server负责SQL解析、优化、执行计划生成
- PD Server管理元数据和调度
- TiKV执行分布式数据存储和查询
查询流程涉及从应用层发起请求,经负载均衡器到达TiDB Server
通过PD获取Region信息,最后TiKV返回数据结果,TiDB整合后返回给客户端
# 01.TiDB架构
# 1、TiDB架构
- TiDB Server是无状态的,可在一个TiDB数据库中启动多个TiDB Server
- 可通过负载均衡软件如LVS、HAProxy、F5等提供统一的接入地址
- 客户端可将连接均匀分摊到多个TiDB Server上,TiDB Server 不存储数据
- 它将传统关系型数据库的
表数据转换为键值对 (key-value) 来存储
TiDB 使用 Region 作为 TiKV 中数据存储的基本单元每个 Region 负责管理一定范围的 key-value 键值对
应用层发起查询请求,通过 MySQL 协议连接到 TiDB 集群LVS 负载均衡层将请求分发到某个 TiDB Server 实例TiDB Server解析、优化查询语句,生成执行计划,向 PD Server 查询数据分布,并通过 TiKV Client 发起查询PD Server返回相关 Region 的分布和位置信息TiKV Server根据请求从对应的 Region 检索数据,并进行过滤、排序等操作,返回给 TiDB ServerTiDB Server整合数据并将最终结果返回给应用程序

# 2、TiDB Server核心能力
- Protocol Layer、Parse、Compile:SQL的解析和编译,生成SQL语句的执行计划,交给Executor
- Executor、DistSQL、KV:分批执行SQL的执行计划
- Transaction、KV:事务的执行
- PD Client、TiKV Client:与PD、TiKV交互
- schema load、worker、start job:online DDL(DDL语句不阻塞读写)
- memBuffer:缓存读取的数据及元数据、登录的认证信息、统计信息等
- GC:垃圾回收

# 3、数据存储方式
- 数据存储方式:关系型数据与 KV 的转换
- TiDB 是一个分布式的 NewSQL 数据库
- 它将传统关系型数据库的
表数据转换为键值对 (key-value) 来存储,主要通过底层的 TiKV 进行分布式存储
# 1)表到 KV 的映射
聚簇表
表的主键和表名一起构成键的前缀,数据行的主键值作为键的后缀,值存储在 TiKV 中
例如,表名为
user的表,主键是user_id,那么该行的数据可能会以{user}_{user_id}这样的形式存储在 TiKV
非聚簇表
- 非聚簇表没有使用主键来生成键,系统会生成一个
row_id作为键,值存储在 TiKV 中
- 非聚簇表没有使用主键来生成键,系统会生成一个
# 2)Region 与分布式存储
TiDB 使用 Region 作为 TiKV 中数据存储的基本单元每个 Region 负责管理一定范围的 key-value 键值对- 当 Region 的大小达到 96MB 时,Region 会进行自动分裂
- 使得数据能够分散存储在不同的 TiKV 节点上,从而实现分布式的存储和负载均衡
# 02.查询场景举例
# 0、场景说明
- 假设一个电商应用需要查询用户购买的订单信息
- SQL 语句为:
SELECT * FROM orders WHERE user_id = 12345 ORDER BY order_date DESC LIMIT 10; - 这个查询的流程如下
# 1、应用层
- 应用层是指发起 SQL 查询请求的地方,例如电商应用的后端服务
- 在这个层级中,应用程序通过 MySQL 客户端驱动与 TiDB 集群交互
处理内容
- 构建查询请求:
- 应用程序使用 SQL 语句构建查询,示例中是通过
user_id查找用户的订单
- 应用程序使用 SQL 语句构建查询,示例中是通过
- 连接 TiDB 集群:
- 应用层通过 MySQL 协议连接 TiDB 集群的 LVS(或负载均衡器),将请求发往 TiDB Server
# 2、负载均衡层
- LVS (Linux Virtual Server) 或者其他负载均衡器如 HAProxy、F5 等
- 在 TiDB 集群中用于将客户端的请求均匀分配到多个 TiDB Server 实例中
- TiDB Server 是无状态的,多个 TiDB Server 可以同时对外提供服务
处理内容
- 负载均衡:
- LVS 接收到应用层发来的 SQL 请求后,根据负载均衡策略(例如轮询、最小连接数等),将请求转发给某个 TiDB Server 实例
- 高可用性:
- 如果某个 TiDB Server 实例发生故障,LVS 可以自动将请求转发到其他健康的 TiDB Server,保证服务的高可用性
举例
- 假设 LVS 检测到有 3 个 TiDB Server 实例可用,它根据负载情况将请求转发到
TiDB Server 1
# 3、TiDB Server 层
# 1)SQL 语句解析与优化
- Parse模块:通过词法分析(lex)、语法分析(yacc) 生成
AST抽象语法树给Compile模块
- 协议解析:TiDB Server 解析客户端的 MySQL 协议,将 SQL 请求转换为内部的数据结构
- SQL 解析 (Parse):
- 通过词法分析和语法分析将 SQL 语句转换为抽象语法树 (AST)
- TiDB Server 解析,并生成对应的 AST
SELECT * FROM orders WHERE user_id = 12345 ORDER BY order_date DESC LIMIT 10;

# 2)SQL 语句编译
编译 (Compile):根据生成的 AST,TiDB 进行验证并生成执行计划
验证:语法验证,如要查询的表在数据库中是否存在等合法性验证逻辑优化:依据关系型代数的一些等价交换的规则,做逻辑变化(在SQL语句层面上的优化)物理优化:根据逻辑优化的结果,考虑数据的物理分布、大小,决定用哪个算子(走索引还是全表扫描?等)
- TiDB Server 通过逻辑和物理优化生成执行计划
- 首先,它会判断是否有合适的索引,如果有索引会选择索引查找,否则会选择全表扫描
- 示例中:TiDB Server 可能通过
user_id字段上的索引进行过滤,减少扫描的范围

# 3)关系型数据与KV的转化
示例
对于
SELECT * FROM orders WHERE user_id = 12345这样的查询请求TiDB 会将查询条件中的
user_id转换为相应的 Key 范围,通过该 Key 查询相关 Region 中的数据Key 的结构:
- 假设
orders表有user_id和order_id,TiDB 可能会将查询的主键(或索引列)转换为键值对查询- 对于
user_id = 12345的数据,TiDB 将根据orders_table+order_id作为 Key 范围来查询对应的数据
- TiDB 将关系型数据存储在 TiKV 中,而 TiKV 是一个分布式的键值存储系统
- 因此需要将表格中的行数据转换为 Key-Value 格式来进行存储
处理内容:
- 聚簇表 (Clustered Table):
- 对于聚簇表,数据是按主键索引组织的,行数据的 Key 是由表名和主键组成,Value 则是该行的数据。
- 例如,对于订单表
orders中user_id = 12345的订单,假设order_id是主键 - 那么 TiDB 会将行数据转换为 Key:
orders_table+order_id,Value 是这一行的具体订单数据
- 非聚簇表 (Non-clustered Table):
- 对于没有主键的表,TiDB 会为每一行生成一个唯一的
rowId,Key 是orders_table+rowId,而不是基于主键
- 对于没有主键的表,TiDB 会为每一行生成一个唯一的
Region 存储单位:
- Region 切分:
- TiDB 将 Key-Value 数据存储在 TiKV 中,每个 TiKV 实例管理多个 Region
- 每个 Region 是一个 Key 范围的存储单位
- TiKV 将 Key-Value 数据按照 Key 的范围进行分布式存储
- 一个 Region 的大小是 96MB,当数据达到上限时
- Region 会自动分裂成两个较小的 Region,分布在不同的 TiKV 结点上
# 4)分布式执行
- 分区 Region 切分:TiDB Server 通过查询 PD Server 获取
orders表中user_id = 12345对应数据的分布(Region 信息),并根据查询条件决定访问哪些 TiKV 节点- 示例中:TiDB 发现
orders表中涉及多个 Region,需要从多个 TiKV 实例中并行检索数据- 执行计划下发:
- TiDB Server 将具体的执行计划下发给 TiKV,通过 TiKV Client 进行数据检索
- 简单查询:
- 对于简单的查询(如主键查询),TiDB 直接通过 KV 模块查询对应的键值对数据
- 通过 TiKV Client,TiDB 向底层的 TiKV 发起读取请求
- 复杂查询 (DistSQL):
- 对于复杂查询(如范围查询、表连接),TiDB 使用 DistSQL 进行分布式计算
- DistSQL 会根据执行计划,将查询分解为多个步骤
- 每个步骤对应不同的 Region 的数据分布,由 TiKV 进行并行执行
- 事务处理:
- 涉及事务的查询会通过 TiDB 的事务模块进行二阶段提交(2PC)
- 事务的提交需要依赖 PD(Placement Driver)提供的时间戳 (TSO),以确保全局一致性
# 4、PD Server 层
- PD (Placement Driver) 是 TiDB 的全局调度组件,负责 TiKV 的元数据管理与调度
- PD 在查询中主要负责处理与数据调度和时间戳相关的事务
# 1)Region 元数据管理
- 查询 Region 信息:
- TiDB Server 向 PD Server 请求
orders表中user_id = 12345对应的数据在哪些 Region 中
- TiDB Server 向 PD Server 请求
- PD Server 会返回这些 Region 的元数据信息,包括每个 Region 所在的 TiKV 节点及其 Key 范围
- 示例中:
- PD Server 发现
orders表的相关数据分布在 3 个不同的 Region 中,这些 Region 分布在不同的 TiKV 节点上
- PD Server 发现
# 2)负载调度
Region 调度如果某些 Region 负载过高,PD Server 可能会对 Region 进行分裂或迁移,以保证负载均衡和查询的高效性
# 3)时间戳分配(事务)
TSO 分配
如果查询涉及事务,PD Server 需要为查询分配全局唯一的时间戳 (TSO),以确保事务的一致性
示例中:虽然这个查询是只读的,但如果是事务查询,PD 会提供时间戳以确保读取的数据是一致的
# 5、TiKV Server 层
- TiKV 是 TiDB 的底层分布式存储引擎,负责存储 TiDB 转换后的键值对数据
- TiKV 通过分布式架构来提供高可用性和水平扩展能力
# 1)读取 Region 数据
Key-Value 存储
TiKV 是一个分布式的 KV 存储引擎
每个 TiKV 节点管理若干个 Region,负责存储特定范围的键值对数据
示例中:TiKV 会从不同的 Region 中并行检索
user_id = 12345的订单数据
数据过滤与投影
TiKV 根据 SQL 的过滤条件(
WHERE user_id = 12345)从存储的键值对中提取对应的数据并根据查询的其他要求(如
ORDER BY和LIMIT)进一步处理结果示例中:TiKV 将查找到的所有订单数据按
order_date排序,并返回最新的 10 条记录
# 2)返回查询结果
- TiKV 将处理后的数据返回给 TiDB Server
- TiDB Server 进行最终的结果整合和格式化后返回给客户端
# 6、TiDB Server 整合返回结果
- 结果整合:
- TiDB Server 接收到 TiKV 返回的查询结果后,进行整合
- 例如对来自多个 TiKV 节点的结果进行排序、去重等,最终生成完整的查询结果
- 结果返回客户端:
- 整合完成后,TiDB Server 将结果通过 MySQL 协议返回给应用程序,应用程序可以对结果进行处理和展示