本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
本作品 (李兆龙 博文, 由 李兆龙 创作),由 李兆龙 确认,转载请注明版权。
文章目录
- 引言
- 技术决策
-
- [JVM vs. Native Execution](#JVM vs. Native Execution)
- [Interpreted Vectorization vs Code-Gen](#Interpreted Vectorization vs Code-Gen)
- [Row vs. Column-Oriented Execution](#Row vs. Column-Oriented Execution)
- [Partial Rollout](#Partial Rollout)
- 总结
引言
SIGMOD 2022的Industry Best Paper
《Photon: A Fast Query Engine for Lakehouse Systems》对于湖仓一体给出了标准的定义:
Many organizations are shifting to a data management paradigm called the "Lakehouse ," which implements the functionality of structured data warehouses on top of unstructured data lakes.
并定义了Lakehouse
对于执行引擎而言最大的挑战就是CPU:
The execution engine needs to provide good performance on the raw uncurated datasets that are ubiquitous in data lakes , and excellent performance on structured data stored in popular columnar file formats like Apache Parquet.
Lakehouse
概念的出现是符合历史发展的,DataLakes
对于性能要求高的工作负载一般会选择将一部分数据结构化后转移到DataWarehouses
中,以实现高性能和Governance
,但是这个过程需要昂贵的ETL
,而且可能导致两端数据不一致[11]。Lakehouse
的数据管理架构在DataLakes
之上提供DataWarehouses
能力,比如Governance
, ACID transactions
以及丰富的SQL
支持,且需要管理的ETL
步骤也更少。其次通过Data Clustering
以及Data Skipping Indices
可以大幅增加存储的访问性能,接下来就是优化计算。
文中给出了计算部分的三个挑战:
- Supporting raw, uncurated data
- Supporting existing Spark APIs
- To be as fast as possible
Photon
与Velox
的定位类似,但是动机完全不同,Velox
是用单一模块化的执行引擎来减少重新实现计算模块的额外人力开销;而Photon
是因为java实现的性能不够,Databricks
作为商业公司增加自己的核心竞争力。这也是为什么Photon
是闭源的,但是世界始终是向前走的,尤其是在这样的一个火热的领域,Apache Gluten
就可以认为是Photon
的开源实现,简单浏览了下Gluten
的代码结构,其支持将Spark Plan
和 Substrait
转化为Velox
,ClickHouse
的执行计划。
说个题外话,Substrait
的流行度越来越高了,除了Apache Gluten
外,Velox
原生支持Substrait
转化为Velox Execution Plan
;Arrow-cpp
原生支持Substrait
转化为Arrow Acero Execution Plan
;基本业界顶级执行引擎都支持了Substrait
,可以认为其已经成为Serialization for Relational Algebra
的事实标准了[13]。
文章本身并没有新东西,但是从工程的角度非常具有借鉴价值,因为其详细的讨论了项目设计的基本技术决策,接下来的文章重点放在这里。
技术决策
JVM vs. Native Execution
这也是文章的核心所在,即Lakehouse
的瓶颈在计算引擎[8]。技术背景为:
local NVMe SSD caching
和autooptimized shuffle
等底层优化大大减少了 IO 延迟Delta Lake
启用的data clustering
等技术允许查询通过file pruning
更积极地跳过不需要的数据,进一步减少了 IO 等待时间Lakehouse
引入了新的工作负载,需要对未规范化数据、大型字符串和非结构化嵌套数据类型进行繁重的数据处理
瓶颈永远不会消失,它只会从一个指标转移到另一个指标,放弃现有JVM引擎的核心观点是目前的瓶颈集中在CPU,提高现有引擎的性能越来越困难,
- 提升性能需要大量的 JVM 内部知识,以确保 JIT 编译器生成最佳代码(比如使用 SIMD 指令的循环)
- 堆的大小超过 64GB时,GC的性能就会受到严重影响,此时需要手动管理堆外内存,增加代码复杂性
- 执行引擎中的
Java code generation
[5][14]受到方法大小或代码缓存大小的限制,可能退化到火山模型,造成性能极具下降
Interpreted Vectorization vs Code-Gen
Vectorization
和Code-Gen
的区别可以学习[16],论文中给出了详细的实验对比,以及两种方法的优劣。
文章提到Databricks尝试了两种方法,最终选择矢量化执行引擎的原因如下:
- Easier to develop and scale :矢量化执行引擎更容易开发,调试器,堆栈跟踪工具等都是现成的,相比之下
Code-Gen
的开发难度就大很多 - Observability is easier :
Code-Gen
通常会将操作符折叠内联到少量流水线函数中,从而消除解释和函数调用开销,但丧失了可观察性 - Easier to adapt to changing data :可以轻松的通过多分支运行时选择代码路径来适应各种情况,
Code-Gen
引擎要做到相同的效果需要在运行时编译过多的分支,或者动态地重新编译查询的部分内容 - Specialization is still possible :虽然
Code-Gen
在某些情况下具有明显的性能优势,但可以通过特殊的工程优化来消除差异,文中给了一个例子,col >= left and col <= right
如果被解释为conjunction
的话会有很高的解释开销,所以Photon
为这样的表达式创建了一个特殊的fused operator
Velox
和Photon
一样,使用矢量化执行引擎,没有混合使用Code-Gen
。
这两种方法其实是可以结合的,框架采用vectorization
,具体到表达式计算可以采用Code-Gen
,达到最高的性能,Clickhouse
就是这样做的,具体可以参考[17][18]
Row vs. Column-Oriented Execution
核心观点如下:
Column-Oriented
更适合SIMD
,通过将操作符作为循环来实现,可以更高效地进行数据流水线处理和预取,并能让exchanges
和spilling
的数据序列化更高效- 执行引擎主要与 Parquet 等列式文件格式对接,列表示可以在扫描数据时跳过昂贵的列到行的转换
- 可以维护字典以减少内存使用
之前我们组自己实现了一个执行引擎,就是存在使用row
做Operator
之间的数据转换导致无法解决的性能问题。
Partial Rollout
这其实不能算是技术取舍而是工程实践中必须要做的,因为不但开源社区会定期积极提供改进、功能和错误修复,其次等功能全做完再上线黄花菜都凉了,这种级别的人力投入是希望尽快看到成果的。
总结
技术细节中有几点比较有意思,但不是文章的重点:
- 将Photon融入Databricks Runtime,因为部分算子Photon是不支持的,还需要使用原生的运算符,这里就涉及到行列转换的问题
- Vectorized Execution 的具体方法,包括
Batched Columnar Data Layout
,Filters and Conditionals
,Vectorized Hash Table
,Vector Memory Management
,Adaptive Execution
文章的重点是笔者深深的感受到了这个领域的卷,Databricks Photon
,Apache Arrow Datafusion
,Apache Arrow Acero
,Meta Velox
,Apache Calcite
,ClickHouse
,DuckDB
等都已经做的非常非常好。Substrait
,Apache Gluten
,这样的项目也是大大降低了使用门槛,技术发展的未来想在性能,成本上超越友商变的越来越困难。
换句话说,顶级开源产品的技术能力一般大公司的绝大多数部门(不是全部,国内互联网公司也拥有一众顶级项目)没有人力做出来,技术规划上如果业界有现成的,且开源许可证允许,对接业界先进开源产品是绝对强于从零到一 ,投入更多精力在运维,可观测性,增值服务上收益更高,当然有能力一定要回馈社区。
其次业务真的很重要,在做一件事情之前务必知道盘子大小(技术型还是关系型不重要),不然风险极高,在此向行业内垂直领域公司致敬,真的很不容易。
参考:
- Photon A Fast Query Engine for Lakehouse Systems
- CMU 15-721
- Photon 基本论文总结
- Photon论文解读 : A Fast Query Engine for Lakehouse Systems
- 深度解读|Spark 中 CodeGen 与向量化技术的研究
- 【Gluten】Spark 的向量化执行引擎框架 Gluten
- 向量化执行引擎框架 Gluten 宣布正式开源,并亮相 Spark 技术峰会
- Spark Commiter 深度解读:Apache Spark Native Engine
- Gluten + Celeborn: 让 Native Spark 拥抱 Cloud Native
- Gluten 首次开源技术沙龙成功举办,更多新能力值得期待
- Lakehouse: A New Generation of Open Platforms that Unify Data Warehousing and Advanced Analytics.
- 从一到无穷大 #26 Velox:Meta用cpp实现的大一统模块化执行引擎
- https://substrait.io/community/powered_by/
- Project Tungsten: Bringing Apache Spark Closer to Bare Metal
- 列存数据库 Code Generation & Vectorized Mode
- Everything You Always Wanted to Know About Compiled and Vectorized Queries But Were Afraid to Ask vldb2018
- Overview of ClickHouse Architecture
- Vectorization vs. Compilation in Query Execution