从一到无穷大 #25 DataFusion:可嵌入,可扩展的模块化工业级计算引擎实现

news2024/11/14 17:12:46

在这里插入图片描述本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。

本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。

文章目录

  • 引言
  • 架构总览与可扩展性
    • Catalog and Data Sources
    • Front End
    • 逻辑计划与逻辑计划优化器
    • 执行引擎
  • 优化
    • 查询重写
    • Sorting
    • 其他
  • 性能
  • 结束语

引言

InfluxDB3.0[11],Greptime使用DataFusion,Lindorm TSDB使用Apache Calcite[8],Db2 Event Store使用内部维护的成熟计算引擎[10],这些业界知名的项目向我们宣告了模块化组件正在推动高性能基础架构领域的发展,计算引擎(DataFusion,Calcite,Velox),一致性引擎(braft,etcd raft),序列化工具(DataFusion-Substrait,),远程数据读取服务(OpenDAL)等已经足够成熟,从现在构建一个项目并不一定要自己实现本身属于公有链路的功能,而应该把精力放在更多增值功能之上

事实上不止我这样想,Andy Pavlo在《Databases in 2022: A Year in Review》中提到:

The long-term trend to watch is the proliferation of frameworks like Velox, DataFusion, and Polars. Along with projects like Substrait, the commoditization of these query execution components means that all OLAP DBMSs will be roughly equivalent in the next five years.

使用开源的执行引擎,所有玩家都将具备同 Snowflake 十年前独有的相同向量化执行能力,当存储层对每个人来说都是相同时(云盘/对象存储),区分 DBMS 产品的关键因素将会是那些难以量化的事物,比如稳定性,UI/UX 设计,查询优化等。好在并不是所有人存储层都一致,这意味着我们可以基于不同的场景设计不同的存储引擎,针对不同场景的存储引擎插件化以及智能化引擎参数调优,并佐以智能索引构建,cache等外部能力建设有竞争力的产品。

这事实上也是我们做多模型数据库的初衷,即用最少的人力/代码完成承载更多的业务,控制面资源管理,调度,arbiter,路由推送,分池,读写链路转化,一致性引擎,wal模块(写入,拉取,同步),备份,多region,部分监控能力等模块共用,协议解析与引擎插件化。

架构总览与可扩展性

请添加图片描述

Datafusion的总体架构可以看作七个部分(数据源,Front End,逻辑计划,逻辑计划优化,执行计划,执行计划优化,执行引擎),与传统高度耦合的系统不同,Datafusion的每个部分用户都可以自由扩展其功能特性,这样不仅可以最大化使用高效稳定的开源代码,也可以在不修改开源代码的情况下实现不同系统的定制功能,我个人认为这就是一个组件类开源项目最大的优势。

Catalog and Data Sources

Datafusion提供了一个目录来存储元数据,比如表格结构,类型,统计信息等,这个信息可以协助执行计划执行时跳过部分数据文件。

对于数据源DataFusion实现了常用文件格式的读取模块,例如Apache Parquet, Apache Avro, JSON, CSV, Apache Arrow IPC files,这些都基于TableProviders模块实现,而且实现了投影,过滤和limit/offset下推的功能。用户也可以使用TableProviders API实现额外的读取模块。

Front End

DataFusion直接使用Arrow的类型系统,在执行的过程中直接使用Arrow数组或者单个值的形式传递数据。

DataFusion 支持sql和DataFrame API,并使用相同的底层逻辑计划表示,当然存在部分系统需要更高级的解析特性,LogicalPlanBuilder API提供了Rust builder-style的接口,用于直接构建逻辑计划

逻辑计划与逻辑计划优化器

DataFusion首先实现了LogicalPlan层面上表示和评估表达式树和关系运算符的全套结构;其次实现了允许使用protobuf和 Substrait 将这些结构序列化/反序列化到适合网络传输的格式;最后携带了解析阶段可能已知的统计信息,如row count、null count和最小/最大值。

除此之外,DataFusion还实现了simplification, interval analysis以及range propagation(减少数据扫描,索引选择,子查询优化,join条件优化)等查询优化策略,并实现了一套ReWrite框架

另外DataFusion又有一个庞大的函数库,可以使用sql和DataFrame 调用,这些函数通过操纵Arrow 数组,使用与用户定义函数相同的API来实现

执行引擎

DataFusion的执行引擎从论文来看没有使用什么巧妙的优化技巧,就是使用pull-base的火山式模型流式执行,允许在多个内核之间分配工作,然后用上一些基础但是有效的实现方式。但是对于我来说还是有很多值得学习的地方,因为我们内部实现了一个完整的执行引擎,用于在时序数据库中支持influxql,当前虽然承载了公司内部大多数的监控数据,但是仍旧属于一个及其早期的阶段。项目内部认为项目初期阶段项目敏捷性,执行引擎的性能,可扩展性,稳定性,远高于其他模块,所以一个成熟执行引擎很多必须的功能都是缺失的,比如论文中提到的很多特性。

  1. 流式执行:所有的运算符都以Arrow 数组的形式递增输出,为了实现矢量化执行,每次拉取都是默认为大小为8192行的RecordBatches,对于full sort, final aggregation, hash join等pipelinebreaking的操作,运算符会对数据进行缓冲,必要时会溢出到磁盘。溢出磁盘这个动作目前来看,是一个极其有效的方法,在实际运营过程中,通常会遇到一个页面一次拉起几十个七天的数据查询,一次就会把时序数据库接入层机器的内存打满,一般我们的接入机都使用CVM,带着一块500GB的cbs盘,但是一般都使用不上,如果可以提供这种数据溢出磁盘的功能,不仅可以防止机器的OOM,而且可以利用上cbs盘的容量。
  2. 多核执行:每个 ExecutionPlan 都使用一个或多个并行执行的 Stream来运行。大多数 Streams 只与它们的输入进行协调,但有些 Streams 必须与同级 Streams 进行协调,如 HashJoinExec 在构建共享哈希表时,或 RepartitionExec 在将数据重新分配到不同 Streams 时。为每个 ExecutionPlan 创建的流的数量称为其分区,分区在执行计划时确定。当然执行引擎的并行化实现还是比较复杂的。我们在存储引擎内部的计算引擎中为了控制并行的数量,控制了一个pod内部允许使用的执行流数量,并控制一个查询允许使用的最大执行流数量。目前来看读取数据(seriesfile,tsi,tsm),解码,过滤,归并操作都可以并行。在计算节点内,计算引擎的并行就麻烦了,为了简化执行计划的过程,目前我们只有解码,归并可以做到并行。
  3. 线程调度:使用tokio作为async-runtime,运行时的实现其实也很有意思,很久以前我使用cpp实现过协作式和抢占式的协程框架,也在dragonfly看到了对于boost.fiber的使用,调度包括不仅限与线程间任务窃取,内部状态trace等。我们内部的多线程管理使用task-flow框架搭配future模型,与协程的使用属于两种异步方式的实现。[4]
  4. 内存管理:DataFusion 使用 MemoryPool 管理内存,一个或多个并发运行的查询共享 MemoryPool。当内存消耗发生重大变化时,Stream会通过调用grow and shrink API 记录。Stream使用一种实用的方法,准确跟踪最大的内存消耗(如用于hash merge的hashTable),但不跟踪小的短暂分配(如当前输出batch的内存)。DataFusion 有两种内置内存池实现。GreedyPool:会强制每个进程的内存限制,但不会试图在查询中将资源公平地分配给各个Stream。FairPool:在所有pipeline-breaking Streams之间平均分配资源。**基于 DataFusion 的系统也允许使用相同的 API,通过特定域策略实现自己的 MemoryPool。**以我们内部的实现来看,因为内部的row没有使用Arrow,而是自己实现的,内存占用不算少,在每个算子迭代器中如果有必要都会生成新的row,这其实会造成大量的内存浪费,还好使用的是cpp,我们可以精确的控制内存使用过的生命周期,但事实上还是有不少的内存占用,所以如果我们要这样做的话也需要记录输出batch的内存。
  5. Cache管理:CacheManager 会缓存目录内容(如昂贵的对象存储 LIST 操作)和每个文件的元数据,如规划和剪枝所需的统计信息。和内存管理一样,需要更多定制策略的用户可提供自己的实现(如驱逐策略或限制临时空间)。在独立的系统中,时序数据库会使用更多的cache策略,当然这是计算引擎之山的行为。另外我也怀疑基于DataFusion实现对象存储的缓存是否是一个好主意,可以给予[9]看到高效的利用对象存储是一个与业务极度挂钩的事情,需要包含对象存储读取线程和实际处理线程的均衡,其次各种业务相关的cache方案也是多种多样的,当然不知道DataFusion有没有提供类似接入API。

优化

查询重写

逻辑计划重写包括projection pushdown, filter pushdown, limit pushdown, expression simplification, common subexpression elimination, join predicate extraction, correlated subquery flattening, and outer-to-inner join conversion。

我们的实现中因为不支持join,所以不支持join predicate extraction和outer-to-inner join conversion;我们支持子查询,但是也不支持 common subexpression elimination和correlated subquery flattening,而projection pushdown, filter pushdown, limit pushdown, expression simplification是支持的。

执行计划重写包括eliminating unnecessary sorts, maximizing parallel execution, and determining specific algorithms(hash merge)。
在我们的系统中支持 maximizing parallel execution, and determining specific algorithms,但是eliminating unnecessary sorts是不支持的。

Sorting

DataFusion中的实现基于[5]。实现了独立的 RowFormat,内存耗尽时溢出到临时磁盘文件的能力,以及对 LIMIT(又名 “Top K”)的专门实现。

我们的实现中也有独立的RowFormat,允许灵活的基于各种排序键进行排序(time,group by tags, order by keys等),其次除了精确的limit实现外,还支持了HyperLogLog,用于快速的,可控资源的返回近似的topk。

但是我们没有内存耗尽时溢出到临时磁盘文件的能力,这个能力可以考虑后续建设,是一个很好的容忍突发大查询的方法。

其他

Grouping,Aggregation,Joins,Window Functions[6]我理解被定义为优化似乎有些牵强,因为基本上所有的计算引擎都会需要这些功能。
Pushdown,Leveraging Sort Order可以被认为是优化,但是也被广泛使用。

在时序数据库中Pushdown是一个极其重要的特性,不仅是Pushdown,还包括SubProcess,这个特性更多的被翻译为协处理器,就是查询被分为N个部分发送到N个节点执行计算操作,随后在一个聚合节点进行二次聚合,利用节点并行的能力带来更多的性能,这个方法使得查询能力几乎可以无限扩展,比如物理pod 54个,用户的表包含54个分片,合理分布下,表所属副本主节点应该均匀的分配在pod之间,那么这个查询可以利用54个pod的计算能力,不仅是腾讯云CTSDBi,谷歌的Monarch[7]和阿里云的Lindorm[8]也深度使用了这个能力。

性能

事实上这样一个拥有活跃社区,且目的明确的开源项目可想而知性能一定会不断演进,目前的性能报告更多的是给大家吃一颗定心丸,也是一种亮出自己拳头的方式。
在这里插入图片描述
ClickBench在单核心与DuckDB各有优劣。

在这里插入图片描述
ClickBench在多核心与DuckDB也是各有优劣。

事实上哪种查询在哪种数据集下谁为什么比谁强,以后能不能做的比彼此更好,已经不是什么重要的事情了,查询引擎这种这么多年没有大的变化的东西,本来就是谁投入大,谁就是大爹,工业性如此强的一种模块想要三个人做个一年半载比别人强基本上不是现实的事情。所以这篇论文中性能对比对绝大多数人来说只需要知道DataFusion具有工业级计算引擎的能力就够了。

结束语

以时序数据库领域看,我认为理论最优架构的InfluxDB3.0与Greptime随着不断的投入,基本性能将趋于一致。但是它强任他强,华为云GaussDB,阿里云Lindorm,腾讯云CTSDBi,TDengine作为架构相对类似的四个系统,虽然投入人力不太对等,但是大家之间的优化方式基本透明,随着时间的发展,最多两年,性能不会有数量级别的差异,刚需功能也会基本对齐,公有云客户看重的更多是价格和稳定性,性能很多时候已经不是最核心的点了(当然性能好赚的多也是实话)。

而Apache IotDB作为学院派作品,基本引领了全球时序数据库近几年科研的方向,每年vldb/sigmod/icde发到手软,但是基本上把自己tsfile的书状索引格式更多的把自己放在拿下传统物联网企业的订单,而且更多的注重边云协同,更多的偏向于解决方案,与公有云要吃的不是一块肉。

参考:

  1. 从一到无穷大 #8 Arrow,Parquet and ORC
  2. Apache arrow datafusion到底是什么?它是伪需求吗?和spark引擎有什么区别?
  3. Morsel-Driven Parallelism: 一种NUMA感知的并行Query Execution框架
  4. CeresDB|Tokio 任务调度原理分析
  5. Implementing sorting in database systems. ACM Comput. Surv. 38, 3 (2006)
  6. Efficient Processing of Window Functions in Analytical SQL Queries vldb2015
  7. 从一到无穷大 #12 Planet-Scale In-Memory Time Series Database, Is it really Monarch?
  8. 从一到无穷大 #13 How does Lindorm TSDB solve the high cardinality problem?
  9. 从一到无穷大 #22 基于对象存储执行OLAP分析的学术or工程经验,我们可以从中学习到什么?
  10. 从一到无穷大 #17 Db2 Event Store,A Purpose-Built IoT Database Engine
  11. Flight, DataFusion, Arrow, and Parquet: Using the FDAP Architecture to build InfluxDB 3.0
  12. 万字带你走过数据库的这激荡的三年

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1645716.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

c3 笔记6 认识css样式表

<link>与import应该如何选择?事实上&#xff0c;使用link与import链接外部样式文件的效果看起来是一样的&#xff0c;区别在于<link>是HTML标记而import属于CSS语法。<link>标记有rel、type与href属性&#xff0c;可以指定CSS样式表的名称&#xff0c;这样就…

深度学习之DCGAN

目录 须知 转置卷积 DCGAN 什么是DCGAN 生成器代码 判别器代码 补充知识 LeakyReLU&#xff08;x&#xff09; torch.nn.Dropout torch.nn.Dropout2d DCGAN完整代码 运行结果 图形显示 须知 在讲解DCGAN之前我们首先要了解转置卷积和GAN 关于GAN在这片博客中已经很…

攻防世界-NewsCenter

题目信息 分析过程 题目打开是有个输入框可以用来输入搜索信息&#xff0c;初步判断是个sql注入的题目。接下来判断能否进行sql注入&#xff1a; 输入 hi&#xff0c;有搜索结果&#xff0c;如下图: 输入hi’,无结果&#xff0c;如下图&#xff1a; 初步判定是hi‘后面还有单引…

【Axure高保真原型】动态伸缩信息架构图

今天和大家分享动态伸缩信息架构图的原型模板&#xff0c;我们可以通过点击加减按钮来展开或收起子内容&#xff0c;具体效果可以点击下方视频观看或者打开预览地址来体验 【原型效果】 【Axure高保真原型】动态伸缩信息架构图 【原型预览含下载地址】 https://axhub.im/ax9/…

Python批量修改图片文件名中的指定名称

批量处理图像时&#xff0c;图片名有时需要统一&#xff0c;本教程仅针对图片中名如&#xff1a;0001x4.png&#xff0c;批量将图片名中的x4去除&#xff0c;只留下0001.png的情况。 如果想要按照原图片顺序批量修改图片名&#xff0c;参考其它博文&#xff1a;按照原顺序批量…

SpringBoot整合rabbitmq使用案例

RocketMQ&#xff08;二十四&#xff09;整合SpringBoot SpringBoot整合rabbitmq使用案例 一 SpringBoot整合RocketMQ实现消息发送和接收消息生产者1&#xff09;添加依赖2&#xff09;配置文件3&#xff09;启动类4&#xff09;测试类 消息消费者1&#xff09;添加依赖2&…

Sy9-dhcp/dns服务配置

前言、 课程需要&#xff08;进入服务器综合配置使用阶段了&#xff09;&#xff0c;这里还是沿用桌面版的ubuntu来配置dhcp和dns&#xff0c;这里updated了新的版本。2024.5 server端环境&#xff1a; Win11VMS&#xff1a;192.168.105.1192.168.105.128 &#xff08;ubuntu…

AI热潮开始退去,财务压力迫使多家硅谷明星初创公司选择退出

曾风光无限的Stability AI已重组并削减业务规模&#xff0c;Inflection AI更是关闭业务并基本并入微软。 5月4日消息&#xff0c;国外媒体日前撰文指出&#xff0c;人工智能的热潮已开始逐渐褪去。初创公司想要同微软、谷歌等科技巨头在人工智能领域一决高下&#xff0c;门槛已…

Spring IoCDI(2)—IoC详解

目录 一、IoC详解 1、Bean的存储 &#xff08;1&#xff09;Controller&#xff08;控制器存储&#xff09; 获取bean对象的其他方式 Bean 命名约定 &#xff08;2&#xff09;Service&#xff08;服务存储&#xff09; &#xff08;3&#xff09;Repository&#xff08…

SPA模式下的多页面跳转原理及实现——jQuery Mobile为例

jQuery Mobile在SPA模式下的多页面跳转原理及实现案例 文章目录 jQuery Mobile在SPA模式下的多页面跳转原理及实现案例前言一、SPA的实现原理和代码分析1.实现原理说明&#xff08;1&#xff09;index.html&#xff08;2&#xff09;index.js&#xff08;3&#xff09;page2.ht…

kafka日志存储

前言 kafka的主题(topic)可以对应多个分区(partition)&#xff0c;而每个分区(partition)可以有多个副本(replica)&#xff0c;我们提生产工单创建topic的时候也是要预设这些参数的。但是它究竟是如何存储的呢&#xff1f;我们在使用kafka发送消息时&#xff0c;实际表现是提交…

一款开源高性能AI应用框架

前言 LobeChat 是一个基于 Next.js 框架构建的 AI 会话应用&#xff0c;旨在提供一个 AI 生产力平台&#xff0c;使用户能够与 AI 进行自然语言交互。 LobeChat应用架构 LobeChat 的整体架构由前端、EdgeRuntime API、Agents 市场、插件市场和独立插件组成。这些组件相互协作&a…

38-1 防火墙了解

一、防火墙的概念: 防火墙(Firewall),也称防护墙,是由Check Point创立者Gil Shwed于1993年发明并引入国际互联网(US5606668 [A]1993-12-15)。它是一种位于内部网络与外部网络之间的网络安全系统,是一项信息安全的防护系统,依照特定的规则,允许或是限制传输的数据通过。…

4个可将 iPhone iPad iPod 修复至正常状态的 iOS 系统恢复软件

许多iOS用户对操作系统问题感到恐慌&#xff0c;例如iPhone卡在恢复模式、白屏死机、黑屏死机、iOS系统损坏、iTunes连接屏幕、iPhone数据丢失等。这些状态通常很无聊&#xff0c;因为您无法使用 iPhone 执行任何操作。 4个可将 iPhone iPad iPod 修复至正常状态的 iOS 系统恢复…

【Unity 组件思想-预制体】

【Unity 组件思想-预制体】 预制体&#xff08;Prefab&#xff09;是Unity中一种特殊的组件 特点和用途&#xff1a; 重用性&#xff1a; 预制体允许开发者创建可重复使用的自定义游戏对象。这意味着你可以创建一个预制体&#xff0c;然后在场景中多次实例化它&#xff0c;…

sip转webrtc方案

技术选型 由于很多企业会议协议用的主要是webrtc&#xff0c;但是项目上很多时候的一些旧设备只支持sip协议&#xff0c;并不支持webrtc协议。所以sip和webrtc的相互转换就很有必要。 流媒体服务mediasoup本身并不支持sip协议。那么如何实现sip转webrtc呢&#xff1f; 根据调研…

我独自升级崛起下载教程 我独自升级崛起怎么一键下载

定于5月8日全球盛大发布的动作RPG力作《我独自升级崛起》&#xff0c;基于备受追捧的同名动画及网络漫画&#xff0c;誓为热情洋溢的游戏爱好者们呈献一场深度与广度兼具的冒险盛宴。这款游戏巧妙融合网络武侠元素&#xff0c;其创意十足的设计框架下&#xff0c;核心叙述聚焦于…

[极客大挑战 2019]PHP

1.通过目录扫描找到它的备份文件&#xff0c;这里的备份文件是它的源码。 2.源码当中涉及到的关键点就是魔术函数以及序列化与反序列化。 我们提交的select参数会被进行反序列化&#xff0c;我们要构造符合输出flag条件的序列化数据。 但是&#xff0c;这里要注意的就是我们提…

力扣每日一题109:有序链表转换二叉搜索树

题目 中等 给定一个单链表的头节点 head &#xff0c;其中的元素 按升序排序 &#xff0c;将其转换为 平衡 二叉搜索树。 示例 1: 输入: head [-10,-3,0,5,9] 输出: [0,-3,9,-10,null,5] 解释: 一个可能的答案是[0&#xff0c;-3,9&#xff0c;-10,null,5]&#xff0c;它…

video标签,如何隐藏右下角三个点包含的功能?

// nodownload: 不要下载 // nofullscreen: 不要全屏 // noremoteplayback: 不要远程回放 // disablePictureInPicture: 不要画中画 <videocontrols disablePictureInPicture"true"controlslist"nodownload nofullscreen noremoteplayback" > </v…