背景介绍
StoneDB 是一款兼容 MySQL 的开源 HTAP 数据库。StoneDB 的整体架构分为三层,分别是应用层、服务层和存储引擎层。应用层主要负责客户端的连接管理和权限验证;服务层提供了 SQL 接口、查询缓存、解析器、优化器、执行器等组件;Tianmu 引擎所在的存储引擎层是 StoneDB 的核心,数据的组织和压缩、以及基于知识网格的查询优化均是在 Tianmu 引擎实现。
本文主要为大家介绍 StoneDB 的读操作、写操作执行过程,方便大家了解引擎架构、内部逻辑和各个功能模块。
一、Tianmu 引擎架构
1 Tianmu 存储引擎在 Server 组件中的位置
2 Tianmu 引擎架构图
3 Tianmu 引擎各个模块介绍
Tianmu Parser
解析客户端传来的 SQL ,进行关键字提取、解析,生成解析树。解析的词包括 select、update、delete、or、group by 等,对不支持的语法会向客户端抛出异常:ERROR:You have an error in your SQL syntax.
比如,执行如下语句:
select * from user where userId =1234;
在分析器中就通过语义规则器将 select、from、where 这些关键词提取和匹配出来, MySQL 会自动判断关键词和非关键词,将用户的匹配字段和自定义语句识别出来。这个阶段也会做一些校验,比如校验当前数据库是否存在 user 表,同时假如 user 表中不存在 userId 这个字段同样会报错:unknown column in field list.
解析入口:
parse_sql()
Tianmu Optimizer
对于来自客户端的请求,首先由查询优化器进行基于知识网格的优化,产生执行计划后再交给执行引擎去处理。基于知识网格中的信息进行粗燥集(Rough Set)构建,并确定此次请求所需使用到的数据包。
优化入口:
optimize_select()
Insert Buffer
InnoDB 的 insert buffer 是为辅助索引的插入做的优化设计,而 Tianmu 的 insert buffer 是为整张表的插入做的优化设计。当向表插入数据时,数据先暂存到 Tianmu 的 insert buffer,然后再从 insert buffer 批量刷新到磁盘,从系统的表现来看是吞吐量提高了。如果不经过 insert buffer,而是直接写入磁盘,由于 Tianmu 不支持事务,只能一行接着一行往磁盘写入,系统的吞吐量是不高的,插入效率固然不高。Tianmu 的 insert buffer 由变量 stonedb_insert_delayed 控制,默认为 on 表示开启。
插入缓存入口:
Engine::insert_buffer
Knowledge Grid Manager
Tianmu 引擎利用知识网格架构来对查询优化器、计划执行和压缩算法等提供支持。知识网格是 Tianmu 引擎进行快速数据查询的关键,在查询计划分析与构建过程中,通过知识网格可以消除或大量减少需要解压的数据块,降低 IO 消耗,提高查询响应时间和网络利用率。 对于大部分统计/聚合性查询,Tianmu 引擎往往只需要使用知识网格就能返回查询结果(而不需要读取数据), 这种情况下在 1s 时间内就可以返回查询结果。
入口函数:
RCAttr::ApproxAnswerSize
Knowledge Grid
Knowledge Grid,即知识网格,是 Tianmu 引擎进行快速数据查询的关键,在查询计划分析与构建过程中,通过知识网格可以消除或大量减少需要解压的数据块,降低 IO 消耗,提高查询响应时间和网络利用率。
KN Node
Knowledge Node(KN Node),即知识节点,除了基础元数据外,还包括数据特征以及更深度的数据统信息,知识节点在数据查询/装载过程中会动态计算。
DPN
Data Pack Node(DPN),即数据包节点,又叫元数据节点(Metadata Node,MD Node),与数据包(DP)之间保持一一对应关系,数据包节点中包含了其对应数据包的元数据信息。
数据结构:
struct DPN{}
获取DPN:
DPN &get_dpn
Data Pack
Data Pack(DP),即数据包,是存储的最底层,列中每份大小固定的单元组成一个数据块。
DP 是存储的最底层,列中每份大小固定的单元组成一个数据块。数据块比列更小,具有更好的压缩比率,又比磁盘默认存储单元单元更 大,具有更好的查询性能。 物理数据按固定数据块存储 (DP)、 数据块大小固定(典型值128KB)、优化 IO 效率、提供基于块 (Block) 的高效压缩/加密算法。
获取 DP:
Pack *get_pack(size_t i)
CMAP
字符过滤、粗集过滤,用于发现可疑数据包并生成字符位图文件。
[En]
Character filtering, rough set filtering to find suspicious packets and generate character bitmap files.
RSIndex_CMap::RSIndex_CMap;
HIST
塑料过滤,粗集过滤,发现可疑包裹,制作直方图文件。
[En]
Plastic filtering, rough set filtering to find suspicious packages, production of histogram files.
RSIndex_Hist::RSIndex_Hist
Replication Manager
StoneDB 复制引擎, StoneDB 本身与常见关系数据库的高可用架构一样(例如 MySQL ),为了保证强一致性,都会将数据更新在 Master 上执行,然后通过复制技术将副本导入到 Slave 节点。但是与 MySQL 标准的 binlog 复制不同,Tianmu 引擎中存储的不是原始数据,而是压缩后的数据块(DP) 。此时如果使用 binlog 的方式来进行复制,会导致网络上产生大量数据流量。为了解决这一点,Tianmu 实现了基于压缩后数据块的高效数据复制支持,相对于 binlog 复制,该技术可以大大降低网络传输所需的数据量。
Compress&Decompress
数据压缩和解压模块,Tianmu 基于列数据类型和特定领域优化的压缩算法,因为列中所有记录的类型一致,可以基于数据类型选择压缩算法,列中重复值越高压缩效果越好。除了常规的压缩算法外,针对特殊场景提供高效的压缩算法,如 Email 地址, IP 地址, URL 等 。
压缩入口:
Compress()
解压入口:
CprsErr Decompress
二、读操作执行过程
对于来自客户端的请求,查询优化器首先基于知识网格进行优化,生成执行计划,然后将其交给执行引擎处理。
[En]
For the request from the client, the query optimizer first optimizes based on the knowledge grid, generates the execution plan, and then gives it to the execution engine to deal with.
- 基于知识网格中的信息进行粗燥集(Rough Set)构建, 并确定此次请求所需使用到的数据包(DP)。
- 根据知识节点和数据包节点,确定查询涉及的数据包集,并对数据包进行分类:
[En]
based on knowledge nodes and packet nodes, determine the set of packets involved in the query, and classify the packets:*
- 相关 DP:满足查询条件限制的 DP(直接读取并返回);
- 可疑 DP:DP 中部分数据满足查询条件(解压后进行处理再返回)
- 不相关 DP:与查询条件完全不相关(直接忽略)。
执行计划构建时, 会完全规避不相关 DP,仅读取并解压相关 DP,按照特定情况决定是否读取可疑 DP。例如,对于一个查询请求,通过 Knowledge Grid 可以确定 3 个相关和 1 个可疑 DP。如果此请求包含聚合函数,此时只需要解压可疑 DP 并计算聚合值,再结合 3 个相关 DP 的数据包节点 (DPN)中的统计值即可得出结果。如果此请求需要返回具体数据,那么无论相关 DP 还是可疑 DP,都需要读取数据块并解压缩,以获得结果集。
- 如果查询请求的结果可以直接从 DPN 中产生(例如 count, max, min 等操作),则直接返回元信息节点中的数据,无需访问物理数据文件。
例如:SELECT count(*) FROM employees where salary < 2500: - 通过 Knowledge Grid 知识,查找包含 salary < 2500 的 DP,此处可以看到只有 A/B/C 三个 DP 涉及到该查询。
- DP A 与 B 属于相关 DP, 只需直接从对应的 DPN 中获取 count 值即可。
- DP C 属于不相关 DP,需要读取数据块并解压,执行函数计算后才能返回结果集。
- 这里只有 DP C 会被读取并解压,DP A 与 B 并不消耗 IO 资源。
执行代码:
Engine::HandleSelect();
Engine::GetTableShare();
class ColumnShare;
ColumnShare::map_dpn();
ColumnShare::read_meta();
ColumnShare::scan_dpn();
TableShare::TableShare();
RCAttr::RoughCheck;
RSIndex_CMap::RSIndex_CMap;
CprsErr Decompress;
TempTable::SendResult();
三、写操作执行过程
来自客户端的请求通过连接器和分析器后,查询优化器根据知识网格进行优化以生成执行计划,该执行计划被压缩和验证,然后移交给执行引擎进行处理。
[En]
After the request from the client goes through the connector and the analyzer, the query optimizer optimizes based on the knowledge grid to generate the execution plan, which is compressed and verified and then handed over to the execution engine for processing.
Tianmu 执行引擎将数据组织为两个层次:物理存储介质上的的数据块(Data Pack,DP),内存上的知识网格层(Knowledge Grid,KG)。
入口函数:
write_row
Original: https://www.cnblogs.com/yangwilly/p/16589387.html
Author: 来来士
Title: StoneDB 读、写操作的执行过程
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/505026/
转载文章受原作者版权保护。转载请注明原作者出处!