DeepSeek smallpond为何选中DuckDB?轻量级分析数据库的“屠龙术“
2月28号,DeepSeek开源周的最后一天发布了两个项目,分别是3FS文件系统,以及利用3FS和DuckDB构建的轻量级数据处理框架Smallpond。其中的DuckDB是一款非常轻量级的嵌入式数据库,为何一款轻量级数据库能扛起AI密集型任务的大旗?今天我们来聊聊这方面的话题。
嵌入式数据库,通俗来说就是可以嵌入到应用程序内部而无需启动外部服务器的数据库。嵌入式数据库最过知名的莫过于SQLite,号称是全球装机量最大的数据库,因为每台手机上可能都有不止一个SQLite数据库。如果说SQLite是主打OLTP场景,那么DuckDB就是要解决嵌入式场景下的OLAP问题。
作为一款新生代的数据库选手,DuckDB有哪些关键的技术特点呢?
DuckDB 的技术特点
极致轻量,无处不在的部署能力
DuckDB 采用C++开发,编译和执行过程中没有额外的依赖,整个源码树被编译成头(header)和实现(implementation)两个文件,极大简化了部署和整合在其他程序的过程。
DuckDB可以在各大主流的操作系统和CPU架构(x86, ARM)上编译,对资源需求没有特别的限制,既可以部署在资源丰富的服务器上,也可以部署在资源有限的边缘设备,甚至是Web浏览器和手机设备上。
功能丰富,轻量化的全能枢纽
DuckDB支持事务,通过多版本并发控制保障事务的ACID属性;深度集成到Python和R中,以实现高效的交互式数据分析;大量的函数库和窗口函数支持复杂的SQL查询。此外还提供了灵活的扩展机制,Parquet文件格式、JSON,HTTP和S3协议等诸多关键功能都是通过扩展来实现的,并且允许定义新的数据类型、函数、文件格式和SQL语法。
很难想象这是一款极简的嵌入式数据库所能做到的!
高速处理,向量化性能加速
DuckDB主要面向OLAP类的分析查询,这类负载的特点是参与计算的数据量比较大,查询语句较为复杂,执行过程相对较长。为了更有效的支持这类负载,DuckDB使用列式向量查询引擎,能够在一个操作中处理一大批数据,显著提升查询性能。
DuckDB是如何融入deepseek smallpond的
尽管DuckDB单机性能强悍,毕竟设计初衷是一款嵌入式的轻量级数据库,但面对海量数据仍然存在不少的限制——而Smallpond的巧妙设计,正是通过Ray框架中赋予了DuckDB“分布式”能力。
首先,smallpond采用惰性计算的方法执行map()、fileter() 等DataFrames操作,这类操作不会立即执行而是构建一个逻辑执行计划,这个计划以DAG(有向无环图)形式表示,其中的每个操作都会对应一个图中的节点。当执行被触发时,逻辑执行计划会被转换成物理执行计划,通过Ray进行分发和执行。
其次,Ray是一个用于构建分布式应用程序的Python开源框架,smallpond的分布式机制通过Ray的分区进行计算任务的分发。每个分区都会在Ray任务中创建一个独立的DuckDB实例,每个任务通过SQL访问各自独立处理分配给自己的分区。
由此可见,smallpond的分布式是在Python层实现的,和Spark/Daft等原生分布式框架有本质的区别。
这种和Ray深度结合的架构,使得smallpond更倾向于通过增加更多标准硬件节点来扩展计算能力,不是提升单个节点的计算性能。根据deepseek公布的数据,在由50个计算节点和25个运行3FS的存储节点构成的集群上,30分14秒的时间内完成了110.5TiB数据的排序,平均吞吐量达到3.66 TiB/分钟,这个成绩甚至超过了以分析型计算能力见长的Clickhouse。
总的来说,smallpond作为一个很好的案例,证明DuckDB能够被用于AI密集型工作负载场景,同时我们也看到可以通过多种方式实现DuckDB的扩展,并且选择合适的扩展策略比默认依赖复杂且庞大的分布式框架更为合理,毕竟靠组件冗余实现的分布式架构成本不菲。
轻量不意味着弱小——DuckDB用模块化设计证明了嵌入式数据库的无限可能。
写在最后
几年前我还沉浸在以Oracle为主流的传统关系型数据库中不可自拔,以为这就是世界之巅。而当跳出Oracle视野再看时,才发现在这之外还有另一番更为广袤的天地。这里的物种功能没有那么强大,可能还存在诸多的限制,因此它们更多的以合作的形态与其他物种共存,在一个大的体系中,每个个体都贡献自己最擅长的能力,这种搭配产生了很多让人惊艳的作品。
多样化的应用场景催生了多样的需求,在AI时代,轻量工具通过生态协作,正在重新定义数据处理的可能性。正如Smallpond通过DuckDB+Ray的组合证明——开源生态中,轻量组件也能迸发远超‘巨无霸’系统的能量。我想这大概也是开源生态最大的魅力吧!