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 协议返回给应用程序,应用程序可以对结果进行处理和展示