1. 背景
常见的CRM, ERP等信息管理系统都基于数据库构建。它们都是常见的TP系统,强调一致性、高并发的在线事务处理(OLTP)系统。这类系统里面有日常的数据增删改查的事务需求,也有周期性的报表需求。TP数据库如PostgreSQL在解决事务型需求时性能卓越,但在处理复杂报表的分析型需求时则表现欠佳,难以高效支持多维度聚合、大规模表关联等操作。传统方案需通过ETL将数据迁移至ClickHouse、Snowflake等专用OLAP系统,导致架构割裂、运维成本陡增。
为了提升TP系统的分析性能,RDS PosgreSQL引入DuckDB,推出了rds_duckdb加速引擎。该引擎利用PostgreSQL扩展插件接口,深度集成DuckDB,实现了一体化的实时事务处理和实时数据分析的能力,一站式满足业务的OLTP及OLAP需求。通过使用rds_duckdb可以获得与原生DuckDB几乎相同的性能,TPCH性能有10-100倍的提升。我们可以将RDS PostgreSQL中的本地表、视图、物化视图等导出为列存表,同时支持行存到列存数据的自动同步。启用分析型查询加速功能后,查询会被在duckdb中执行,非常适合实时报表等复杂分析场景。
2. 什么是DuckDB
DuckDB【1】【2】是一款面向嵌入式分析场景的高性能开源列式关系型数据库,专注于复杂SQL查询的加速与大规模数据分析(OLAP)。该项目由荷兰国家数学与计算机科学研究院(CWI)的 Mark Raasveldt 和 Hannes Mühleisen 主导开发,于2019年正式开源,凭借其卓越的AP性能与轻量级设计,迅速成为数据科学和边缘计算领域的热门选择,月下载量超百万次。其核心优势在于以单机进程内(in-process)架构高效处理百列级宽表及十亿行级数据量的复杂分析,例如多表关联聚合、窗口函数计算等场景。与SQLite等传统嵌入式数据库的OLTP定位不同,DuckDB深度优化列式存储、向量化执行引擎及并行计算,特别适配Python/R生态的数据分析、BI工具嵌入式加速等场景。截至2024年,其GitHub Star数已突破24.7k,社区贡献者超500人,版本迭代速度与性能优化持续领跑开源OLAP领域。
3. DuckDB为什么这么快
DuckDB从优化器,执行器,操作符,和存储等各个环节都利用了业界最新的技术,并凭借强大的工程能力,实现了单机复杂查询的极致性能,超过了同类分析型数据库。这里仅对DuckDB的优化点做一个简单的概述,具体的实现细节可以参考引用文档。
3.1 优化器
在很少甚至没有统计信息的情况下,连接顺序优化器(join order optimzier)【3】通过减少连接过程中处理的中间元组数量,显著提升了多表join查询性能。具体优化点如下:
通过减少多表连接时的中间结果规模,提升复杂查询的执行效率;
在Join Order枚举过程中,采用高效的搜索策略,平衡探索空间与计算开销,避免传统动态规划方法的高复杂度问题;
轻量化统计依赖:结合轻量级信息生成优化策略,降低对传统统计信息的依赖,适应实时分析场景。
3.2 执行器
3.2.1 列向量化执行(columnar-vectorized query execution engine)
DuckDB采用列向量化执行提升查询的性能。
[4]
向量化查询执行指的是数据库引擎中的一种方法,它通过批量处理数据而不是逐行处理数据来增强查询性能。这种方法通过利用现代CPU架构及其执行单指令、多数据 (SIMD) 操作的能力,提高了CPU的数据处理效率。
向量化查询执行通过将称为向量的数据块加载到CPU缓存中,并在这些数据上执行批量操作来运行。其主要特点包括:
批量处理:以大块数据处理,减少与处理单个数据点相关的开销。
单指令多数据 (SIMD) 优化:通过同时对多个数据点执行相同的操作来最大限度地提高效率。
列式读写:仅处理查询相关的列,而不是整个数据集,从而简化操作。
3.2.2 基于推送的执行(push based execution)
DuckDB采用推送的执行模型提高并行度从而提升查询的性能。
基于推送的处理是一种查询处理模型,数据从底层的操作符推送到上层的操作符,整体执行的控制流是自底向上。
[5]
数据其中系统中的每个操作符自行决定是否并行执行,而不是依赖于集中执行器。DuckDB 采用这一模型,是因为原来的基于拉取(pull based execution)的向量化查询处理在添加额外操作符时遇到了挑战。基于推送的处理模型允许更灵活和高效地同时执行多个管道,提高了系统处理复杂并行性和高效操作的能力。
拉取模型往往需要在计划生成阶段就决定好并行度,DuckDB的推送模型实现了Morsel-Driven Parallelism:
- 查询被划分为多个pipeline,即执行计划可以划分为多个部分并行执行;
- 每个操作符自行决定是否并行执行,同时操作符间的并行互相能感知到。
下图是一个三张表join的例子,左边为关系代数表达式,右边为并行化执行的过程。
[6]
推送模型还开辟了额外优化和更细粒度控制系统的可能性。其中包括使用向量缓存(Vector Cache)在操作符之间缓冲结果,直到填满向量。此外,扫描共享(Scan Sharing)涉及在有向无环图(DAG)计划中将一个子操作符的结果推送给多个父操作符。在中央位置存储状态还支持反压(Backpressure)/异步IO(Async IO),即在缓冲区满时或等待远程IO时暂停操作符执行。这种细粒度控制使得在数据库系统内能够进行更高效和优化的查询处理。
3.3 操作符(operator)优化
DuckDB针对执行器中的核心算子(包括sort,aggregationg等等)做了大量优化,以此来提升查询性能。
3.3.1 sort【7】【8】
DuckDB针对列存排序做了多项优化,包括利用了索引避免排序,内存与磁盘排序的切换,并行化排序,和延迟物化等等技术手段,实现了极致的排序性能。
3.3.2 hash aggregation【9】【10】
针对hash aggregation操作符,采用分区和并行化的优化,同时考虑内存和磁盘的交换情况,提升执行性能。
RDS DuckDB架构&性能
从以上架构图可以看到:
- 数据同步:PG中全量行存数据导入rds_duckdb插件中,转换为列存数据,并开启增量数据同步。其中增量同步基于PG原生逻辑复制实现。
- 查询处理:分析查询路由到rds_duckdb插件中,经过向量化并行执行算子产生查询结果,然后经过类型转换返回给客户端。
3.4 核心优势
- HTAP性能优异:PG在OLTP方面本身具备良好性能,同时DuckDB在OLAP上性能优势明显。
- 语法高度兼容:由于DuckDB语法解析使用了PG的语法解析器,因此rds_duckdb插件实现了对PG语法的高度兼容。
3.5 适用场景
特别适合对于业务数据已经在RDS PG中,对分析数据的时效性有要求的场景。
- 离线分析:定时数据批量导入,离线报表业务
- 实时分析:实时数据分析需求的场景,如实时报表。
3.6 性能对比
测试数据量:TPCH 100X。测试过程可以参考rds_duckdb官网文档中的TPC-H示例。
rds_duckdb 对比 RDS PG
在开启rds_duckdb AP加速后,相较于RDS PG,查询性能有了极大幅度的提升,下图展示了TPC-H的22条查询语句执行时间对比,rds_duckdb基本都在3s内完成,其中Q2、Q15、Q17、Q18、Q20、Q21在RDS PG中执行超过10min(测试中设置单SQL超时时间为10min)。
rds_duckdb 对比 clickhouse
图中共16条SQL,Q8、Q9因为机器内存不足运行有问题,Q19超过10min未运行出结果,Q20~Q22目前并不支持(CK TPC-H官网文档)
3.7 压缩对比
下图对比了TPC-H 100X测试数据中一些表,分别在rds_duckdb、RDS PG以及开源版本ClickHouse中的大小。其中rds_duckdb导出的列存表具有最高的压缩比,可以有效节省空间。
3.8 总结
通过上面的性能和压缩数据,可以看到rds_duckdb的特点:
- 性能优异:在复杂的查询中加速效果明显,甚至可以达到百倍、千倍。
- 资源友好:相较于CK可以使用更少的内存完成查询。
- 压缩比高:导出列存文件有很高的压缩比,有效节省空间。
抢先体验,参见RDS PG官网文档:AP加速引擎(rds_duckdb);
更多咨询,可以加入钉钉RDS PG插件交流群了解:103525002795 ;
参考文档:
参考一:DuckDB: an Embeddable Analytical Database (SIGMOD 2019 Demo)
参考二:Why DuckDB
参考三:Join Order Optimization with (Almost) No Statistics (Master thesis, 2022)
参考四:In-Process Analytical Data Management with DuckDB
参考五:Push versus pull-based loop fusion in query engines
参考六:Paper Reading: Morsel-Driven Parallelism
参考七:These Rows Are Made for Sorting and That's Just What We'll Do (ICDE 2023)
参考八:Fastest Table Sort in the West – Redesigning DuckDB’s Sort
参考九:Robust External Hash Aggregation in the Solid State Age (ICDE 2024)
参考十:Parallel Grouped Aggregation in DuckDB
来源 | 阿里云开发者公众号
作者 | 日休