9.TiDB数据库的计算

SQL 层简介

TiDB 的 SQL 层,即 TiDB Server,负责将 SQL 翻译成 Key-Value 操作,将其转发给共用的分布式 Key-Value 存储层 TiKV,然后组装 TiKV 返回的结果,最终将查询结果返回给客户端。

这一层的节点都是无状态的,节点本身并不存储数据,节点之间完全对等。

SQL 运算

最简单的方案就是通过上一节所述的表数据与 Key-Value 的映射关系方案,将 SQL 查询映射为对 KV 的查询,再通过 KV 接口获取对应的数据,最后执行各种计算。

比如 select count(*) from user where name = "TiDB" 这样一个 SQL 语句,它需要读取表中所有的数据,然后检查 name 字段是否是 TiDB,如果是的话,则返回这一行。具体流程如下:

  1. 构造出 Key Range:一个表中所有的 RowID 都在 [0, MaxInt64) 这个范围内,使用 0 和 MaxInt64 根据行数据的 Key 编码规则,就能构造出一个 [StartKey, EndKey)的左闭右开区间。

  2. 扫描 Key Range:根据上面构造出的 Key Range,读取 TiKV 中的数据。

  3. 过滤数据:对于读到的每一行数据,计算 name = "TiDB" 这个表达式,如果为真,则向上返回这一行,否则丢弃这一行数据。

  4. 计算 Count(*):对符合要求的每一行,累计到 Count(*) 的结果上面。

整个流程示意图如下:

这个方案是直观且可行的,但是在分布式数据库的场景下有一些显而易见的问题:

  • 在扫描数据的时候,每一行都要通过 KV 操作从 TiKV 中读取出来,至少有一次 RPC 开销,如果需要扫描的数据很多,那么这个开销会非常大。

  • 并不是所有的行都满足过滤条件 name = "TiDB",如果不满足条件,其实可以不读取出来。

  • 符合要求的行的值并没有什么意义,实际上这里只需要有几行数据这个信息就行。

分布式 SQL 运算

为了解决上述问题,计算应该需要尽量靠近存储节点,以避免大量的 RPC 调用。首先,SQL 中的谓词条件 name = "TiDB" 应被下推到存储节点进行计算,这样只需要返回有效的行,避免无意义的网络传输。然后,聚合函数 Count(*) 也可以被下推到存储节点,进行预聚合,每个节点只需要返回一个 Count(*) 的结果即可,再由 SQL 层将各个节点返回的 Count(*) 的结果累加求和。

以下是数据逐层返回的示意图:

SQL 层架构

通过上面的例子,希望大家对 SQL 语句的处理有一个基本的了解。实际上 TiDB 的 SQL 层要复杂得多,模块以及层次非常多,下图列出了重要的模块以及调用关系:

用户的 SQL 请求会直接或者通过 Load Balancer 发送到 TiDB Server,TiDB Server 会解析 MySQL Protocol Packet,获取请求内容,对 SQL 进行语法解析和语义分析,制定和优化查询计划,执行查询计划并获取和处理数据。数据全部存储在 TiKV 集群中,所以在这个过程中 TiDB Server 需要和 TiKV 交互,获取数据。最后 TiDB Server 需要将查询结果返回给用户。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值