暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

DuckDB:开篇

coredump 2021-05-22
2344

DuckDB 简介

最近发现了一个适合深入学习的开源分析型数据库——DuckDB[1]。简单说,DuckDB 是一个 OLAP[2](列存)版本的 SQLite[3]

作为了一个学习样例,DuckDB 具有以下优点:

  1. DuckDB 没有外部依赖,所以编译、链接、运行都可以一气呵成,非常简单。
  2. 代码不算多,除去测试代码,大概 13~14w 行,并且代码质量不错。
  3. 麻雀虽小,五脏俱全。并且 DuckDB 遵循教科书上的经典模块设计,相对容易看懂。
  4. DuckDB 集成了 OLAP 领域的各种知识,它的各种设计、实现都可以找到参考论文,方便学习。

对比 LevelDB

之前也写过一系列 LevelDB 源码解析的文章

代码量上,LevelDB 大概也就 2w 行,比 DuckDB 少很多。

功能上,LevelDB 只是一个简单的 key-value 存储。而 DuckDB 则是一个完成的数据库——SQL Parser、Optimizer、Execution Engine、Transaction、Storage 一个不少。

DuckDB 的模块介绍

SQL Parser

DuckDB 的 SQL parser[4] 是从 Postgres 的 libpg_query [5]精简而来的。由于 Postgres 是 C 语言写的,通过这个 SQL parser,我们会得到一个 C 语言结构体表示的 parse tree。DuckDB 会将其转换成自己内部的 C++ 对象。

Logical Planner

Logical planner[6] 由 binder 和 plan generator 两部分组成。Binder 将 parse tree 与 schema 的信息(列名、类型等)绑定起来。Schema 信息保存在 catalog[7]。Plan generator 将 parse tree 转换成一颗逻辑查询操作符(scan, filter, project 等)树。

Optimizer

DuckDB 实现了基于规则(rule-based)和基于代价(cost-based)的优化器。Optimizer[8] 的主要任务是优化 SQL,它将前面 logical planner 生成的 logical plan 转换成一个等价但执行代价更小的 logical plan。常见的优化方式有谓词下推(predicate pushdown)、表达式重写(expression rewriting)、调整 join 顺序(join ordering)等。

Physical Planner 和 Execution Engine

Physical planner 和 execution engine 的代码都在 execution [9]目录下。Physical planner 将 Logical plan 转换成 physical plan。Physical plan 是一个真正可以执行的物理计划。DuckDB 实现了一个向量化(vectorized)的解释型执行引擎。向量化可以利用 CPU 提供的 SIMD 指令加速计算。DuckDB 采用 SQL 的解释执行,而没有采用 SQL 的编译执行,原因是编译执行需要依赖编译组件,比如 LLVM,这会导致 DuckDB 的体积膨胀不少。

Transaction and Concurrency Control

DuckDB 支持 Serializable 的事务隔离。事务相关的代码在 transaction [10]目录下。

Storage

Storage [11]是 DuckDB 的列式存储引擎,处于整个 DuckDB 架构的最底层,负责提供数据的高效读写。

编译运行

DuckDB 的下载和编译很简单:

git clone https://github.com/duckdb/duckdb
cd duckdb
BUILD_BENCHMARK=1 BUILD_TPCH=1 make

编译完成后,我们可以得到一个 DuckDB 的二进制库+头文件。另外,我们得到一个 benchmark 程序,可以用来测试 DuckDB 的性能。

# 列出所支持的 benchmark 
build/release/benchmark/benchmark_runner --list

# 运行指定的一个 benchmark
build/release/benchmark/benchmark_runner benchmark/tpch/sf1/q01.benchmark

# 运行某个目录下的 benchmark
build/release/benchmark/benchmark_runner 'benchmark/tpch/sf1/.*'

# 运行所有 benchmark
build/release/benchmark/benchmark_runner

关于 benchmark_runner 的更多功能,可以参考官方文档[12]

参考资料

[1]

DuckDB: https://duckdb.org/

[2]

OLAP: https://en.wikipedia.org/wiki/Online_analytical_processing

[3]

SQLite: https://www.sqlite.org/index.html

[4]

SQL parser: https://github.com/duckdb/duckdb/tree/v0.2.6/src/parser

[5]

libpg_query : https://github.com/lfittl/libpg_query

[6]

Logical planner: https://github.com/duckdb/duckdb/tree/v0.2.6/src/planner

[7]

catalog: https://github.com/duckdb/duckdb/tree/v0.2.6/src/catalog

[8]

Optimizer: https://github.com/duckdb/duckdb/tree/v0.2.6/src/optimizer

[9]

execution : https://github.com/duckdb/duckdb/tree/v0.2.6/src/execution

[10]

transaction : https://github.com/duckdb/duckdb/tree/v0.2.6/src/transaction

[11]

Storage : https://github.com/duckdb/duckdb/tree/v0.2.6/src/storage

[12]

官方文档: https://github.com/duckdb/duckdb/blob/v0.2.6/benchmark/README.md


文章转载自coredump,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论