前言

Databend 在 2021 年开源后,连续受到了很多社区同学的重视。Databend 运用了 Rust 编程语言。为了招引更多的开发者,特别是没有 Rust 开发阅历的新同志,咱们规划了 Rust 相关课程,同时建立了多个 Rust 兴趣小组。
Databend 在 issue 中还引入了“Good First issue”的 label 来引导社区新同学参加第一次贡献,目共有超过一百多位 contributors,算是一个不错的效果。 但 Databend 也在过去的一年中阅历了数次迭代,代码日渐复杂。现在代码骨干分支有 26 w 行 rust 代码,46 个 crate,对于新接触 Databend 的技能爱好者来说,贡献门槛越来越高。即使是了解 rust 的同学,clone 代码后,面对着茫茫码海,竟不知如何读起。在多个社区群中,也有朋友数次提到什么时候能有一个 Databend 源码阅览系列文章,协助咱们更快了解 Databend 代码。
因而,咱们接下来会开展“Databend源码阅览”系列文章,首要受众是社区技能开发者,期望经过源码阅览,来加强和社区的技能沟通,引发更多思维磕碰。Databend 的故事

Databend 的故事

很多同学都问过咱们一个问题:为什么你们要用 Rust 从零构建一个数据库?其实这个问题能够分为两个子问题:

1.为什么挑选的是 Rust?

答:咱们早期的成员大多是 ClickHouse、tidb 、tokudb 等知名数据库的贡献者,从技能栈来说更了解的是 C++ 和 Go。虎哥@bohutang 在疫情期间也运用 Go 完成了一个小的数据库原型 vectorsql有同学表明 vectorsql 的架构十分优雅,值得学习学习。

Databend 源码阅读系列(一): 开篇
语言本没有孰劣之分,要从面向的场景来聊聊。现在大多的 DMBS 运用的是 C++/Java,新式的 NewSQL 更多运用的是 Go。在以往的开发阅历来看,C/C++ 已经是高性能的代名词,开发者更容易写出高运转功率的代码,但 C++ 的开发功率真实不忍直视,东西链不是很完善,开发者很难一次性写出内存安全,并发安全的代码。而 Go 或许是别的一个极端,大道至简,东西链完善,开发功率十分高,不足之处在于泛型的进度太慢了,在 DB 体系上内存不能很灵敏的控制,且难于到达前者的运转性能,尤其运用 SIMD 指令还需求和汇编代码交互等。咱们需求的是兼具 开发功率(内存安全,并发安全,东西链完善)& 运转功率 的语言,当时看来,Rust 或许是咱们仅有的挑选了,历经尝试后,咱们也发现,Rust 不只能满足咱们的需求,并且很酷!

2.为什么要从零构建一个数据库体系?

总体来说,道路无非就以下两条:

  • 根据知名的开源数据库做二次开发优化

这条道路或许更多人会挑选,因为有一个好的数据库底座,无需再做一些重复性的作业,在上面做二次开发的话能省不少力气,团队专注做优化改进重构,能更早推进版别,落地商业化。缺点是 fork 后的版别难于再次回馈到社区,相当于别的一套独立的体系,如 PG 下的各个子流派。

  • 从零构建一套新的数据库体系

这条道路走起来比较困难,因为数据库体系真实太巨大了,一个子方向都满足专业人士深入研究十几年。这个方向尽管没能直接站在已有的底座上,但会让规划者愈加灵敏可控,无需重视太多历史的包袱。Databend 在规划之初面向的是云原生数仓的场景,和传统的数据库体系有很大的差异,假如根据传统数据库体系来做,改造代码的本钱和从零做的本钱或许差不多,因而咱们挑选的是这条路来从零打造一个全新的云数仓。

Databend 的架构

画虎画皮难画骨,咱们先从 Databend 的“骨”聊起

Databend 源码阅读系列(一): 开篇

尽管咱们是运用 Rust 从零开始完成的,但不是彻底闭门造轮子,一些优秀的开源组件或者生态也有在其间集成。如:咱们兼容了 Ansi-SQL 标准,供给了 MySQL/ClickHouse 等干流协议的支撑,拥抱了万物互联的 Arrow 生态,存储格局根据大数据干流的 Parquet 格局等。咱们不只会积极地回馈了贡献给上游,如 Arrow2/Tokio 等开源库,一些通用的组件咱们也抽成独立的项目开源在 Github(openraft, opendal, opencache, opensrv等)。

Databend 界说为云原生的弹性数据库,在规划之初咱们不只要做到核算存储别离,每一层的极致的弹性都是规划首要考量点。Databend 首要分为三层:MetaService Layer,Query Layer,Storage Layer,这三层都是能够弹性扩展的,意味着用户能够为自己的事务挑选最适合的集群规模,并且随着事务发展来弹性集群。

下面咱们将从这三层来介绍下 Databend 的首要代码模块

Databend 的模块

  • MetaService Layer

MetaService 首要用于存储读取耐久化的元数据信息,比方 Catalogs/Users 等。

包名 效果
metasrv MetaService 服务,作为独立进程部署,可部署多个组成集群,底层运用 Raft 做分布式共识,Query 以 Grpc 和 MetaService 交互。
common/meta/types 界说了各类需求保存在 MetaService 的结构体,由于这些结构体终究需求耐久化,所以触及到数据序列化的问题,当时运用 Protobuf 格局来进行序列化和反序列化操作,这些类型相关的 Rust 结构体与 Protobuf 的彼此序列化规矩代码界说在 common/proto-conv 子目录中。
common/meta/sled-store 当时 MetaService 运用 sled 来保存耐久化数据,这个子目录封装了 sled 相关的操作接口。
common/meta/raft-store openraft 用户层需求完成 raft store 的存储接口用于保存数据,这个子目录就是 MetaService 完成的 openraft 的存储层,底层依赖于 sled 存储,同时这儿还完成了 openraft 用户层需求自界说的状态机。
common/meta/api 对 query 露出的根据 KVApi 完成的用户层 api 接口。
common/meta/grpc 根据 grpc 封装的 client,MetaService 的客户端运用这儿封装好的 client 与 MetaService 进行通信交互。
raft github.com/datafuselab… async-raft 项目中衍生改进的全异步 Raft 库。
  • Query Layer

Query 节点首要用于核算,多个 query 节点能够组成 MPP 集群,理论上性能会随着 query 节点数水平扩展。SQL 在 query 中会阅历以下几个转换过程

Databend 源码阅读系列(一): 开篇

从 SQL 字符串经过 Parser 解析成 AST 语法树,然后经过 Binder 绑定 catalog 等信息转成逻辑方案,再经过一系列优化器处理转成物理方案,最终遍历物理方案构建对应的履行逻辑。query 触及的模块有:

包名 效果
query Query 服务,整个函数的进口在 bin/databend-query.rs其间包括一些子模块,这儿介绍下比较重要的子模块:1.api:对外露出给外部的 HTTP/RPC 接口2.catalogs:catalogs 办理,现在支撑默许的 catalog(存储在 metaservice)以及 hive catalog (存储在 hive meta store)3.Clusters:query 集群信息4.Config:query 的装备相关5.databases:query 支撑的 database engine 相关6.evaluator:表达式核算东西类7.Interpreters:SQL 履行器,SQL 构建出 Plan 后,经过对应履行器去做物理履行8.pipelines:完成了物理算子的调度结构9.Servers:对外露出的服务,有 clickhouse/mysql/http 等10. Sessions:session 办理相关11. Sql:包括新的 planner 规划,新的 binder 逻辑,新的 optimizers 规划12. Storages:表引擎相关,最常用为 fuse engine13. table_functions:表函数相关,如 numbers
common/ast 根据 nom_rule 完成的新版 sql parser
common/datavalues 各类 Column 的界说,表明数据在内存上的布局, 后续会逐渐迁移到 common/expressions
common/datablocks Datablock 表明 Vec 集合,里边封装了一些常用方法, 后续会逐渐迁移到 common/expressions
common/functions 标量函数以及聚合函数等完成注册
common/hashtable 完成了一个线性探测的 hashtable,首要用于 group by 聚合函数以及 join 等场景
common/formats 负责数据对外各类格局的 序列化反序列化,如 CSV/TSV/Json 格局等
opensrv github.com/datafuselab…
  • Storage Layer

Storage 首要触及表的 Snapshots,Segments 以及索引信息等办理,以及和底层 IO 的交互。Storage 现在一大亮点是根据 Snapshot 隔离 完成了相似 Iceberge 方法的 Increment view, 咱们能够对表在任意历史状态下进行 time travel 拜访。

后续规划

源码阅览系列刚刚开始编撰,后续预计将按照介绍各个模块的方法进行逐渐解说,输出首要以文章为主,一些比较重要且风趣的模块规划或许会以视频直播的方法和咱们一同沟通。 现在仅仅一个初步的规划,在这个过程中会承受咱们的建议做一些时刻内容调整。无论如何,咱们都等待经过这个系列的活动,让更多志同道合的人参加到 Databend 的开发中来,一同学习沟通成长。关于 Databend关于 DatabendDatabend 是一款开源、弹性、低本钱,根据对象存储也能够做实时分析的新式数仓。等待您的重视,一同探究云原生数仓解决方案,打造新一代开源 Data Cloud。

关于 Databend

Databend 是一款开源、弹性、低本钱,根据对象存储也能够做实时分析的新式数仓。等待您的重视,一同探究云原生数仓解决方案,打造新一代开源 Data Cloud。

  • Databend 文档:databend.rs/

  • Twitter:twitter.com/Datafuse_La…

  • Slack:datafusecloud.slack.com/

  • Wechat:Databend

  • GitHub :github.com/datafuselab…

Databend 源码阅读系列(一): 开篇
文章首发于公众号:Databend