最近一直有社区的小伙伴问,我们很感兴趣CnosDB,但从何开始阅读CnosDB的代码呢,其实这个问题在之前的CnosDB HiTea直播时就有聊到,今天我们就再来回顾一下。
Query Engine 的源码阅读
CnosDB查询步骤大致如下:
解析 SQL 语句成 Statement
根据 Statement 生成逻辑计划
基于规则优化查询逻辑计划
根据逻辑计划生成物理计划
基于代价优化物理计划
执行计划
其中 DDL 语句没有 3、4、5 步骤。
CnosDB查询请求的入口代码在 main/src/http/http_service.rs 中的query 函数下。一次 http 的 query 请求中,参数携带用户和 DB 名, 根据此进行用户认证,并生成执行 SQL 的上下文。在 query_server/query/src/dispatcher/manager.r 的 execute_query 函数下开始处理 SQL。
1.解析 SQL。解析成 ExtStatement 这个结构体,该结构体代表 SQL 的语法树。ExtStatement 结构体可以在 query_server/spi/src/query/ast.rs 看到。大致分为两类,一类是 DQL 和 DML,其中包括 SELECT、 INSERT 语句,另一类是 DDL,包括 CREATE、 DROP 语句。
2.生成逻辑计划。是根据 Statement 生成逻辑计划,转换的这部分代码在 query_server/query/src/sql/planner.rs。在生成逻辑计划时,会对元数据进行访问,来判断 Statement 的语义是否正确。
3.优化逻辑计划。这部分的入口代码在 query_server/query/src/execution/query.rs 和 query_server/query/src/sql/optimizer.rs 中。逻辑计划的优化是基于规则的,包括谓词下推、简化表达式等规则。其中 DDL语句,不需要优化逻辑计划,跳过 3、4、5 步。
4.逻辑计划转物理计划。比如连接就有排序连接,哈希连接等不同实现。
5.优化物理计划。物理计划的优化是基于代价的,比如根据表的数据量优化连接的主表,这步的入口代码在 query_server/query/src/sql/optimizer.rs 处。
6.执行计划。DDL的执行大多是访问元数据并修改,这部分代码在 query_server/query/src/execution/ddl 中。而 DQL 往往是扫描表,并用谓词过滤,中间可能有连接操作,投影操作,聚合操作。其中最基础的步骤就是扫描表(TableScan),TableScan 会生成一个表数据的迭代器,迭代器的操作元素是 RecordBatch(是一种 DataFrame 结构)。之后在迭代器返回的 RecordBatch 上执行操作。这些操作包括过滤,连接,聚合,并且往往是向量化执行的。
数据流程图
Storage Engine 的源码阅读
关于分布式
小结
参与CnosDB社区交流群:
扫描下方二维码,加入 CC 进入 CnosDB 社区进入社区交流,CC 也会在群内分享直播链接哒



🚪由此下方【阅读原文】即可传送CnosDB GitHub开源社区🔜🎟 各位爱码士🧙♂️尽情享受开源世界吧。