LLVM技术在GaussDB等数据库中的应用

目录

LLVM和数据库

LLVM适用场景

LLVM对所有类型的SQL都会有收益吗?

LLVM在OLTP中就一定没有收益吗?

GaussDB中的LLVM

1. LLVM在华为应用于数据库的时间线

2. GaussDB LLVM实现简析

3. GaussDB LLVM支持加速的场景

支持LLVM的表达式:

支持LLVM的算子:

4. GaussDB LLVM使用建议

GUC参数:

5. GaussDB LLVM性能表现

PostgreSQL中的LLVM

1. LLVM在PostgreSQL应用的时间线

2. PostgreSQL LLVM实现简析

3. PostgreSQL LLVM支持加速的场景

总结


万物互联的态势下,数据量的激增使得“如何提升数据处理性能”成为各家数据库共同面临的挑战。作为编译优化技术的代表,基于LLVM的CodeGen技术,能为每个查询生成定制的机器码替代原本的通用函数,减少实际查询时冗余的条件逻辑判断、虚函数调用并提高数据局域性,从而达到提升查询整体性能的目的,成为数据库性能优化的一项重要技术。

LLVM能在分析类场景中给用户带来较大的收益,也能在特定的交易性场景中给用户带来一定的收益。接下来详细解读一下LLVM技术在GaussDB等数据库中的应用吧。

LLVM和数据库

LLVM(Low Level Virtual Machine)是一款流行的开源编译器框架,是CodeGen(生成源代码的工具)技术的事实标准,被广泛运用于数据库(如KES, AnalyticDB, GaussDB)、大数据(如Spark)、AI平台(如tensorflow)等领域,用于提升数据处理的性能。

在没有引入LLVM这类CodeGen技术之前,数据库会使用通用的处理逻辑来处理数据。但通用逻辑“笨重”(递归、封装、类型判断转换)的代码实现方式,存在虚函数开销、缓存使用率低下、对指令集不敏感等性能短板。

引入LLVM之后,可以为具体的查询生成定制化的机器码,并尽可能地将数据存储在CPU的寄存器中进一步加快计算的速度:

  • LLVM天然支持JIT,该技术可以解决条件逻辑冗余的问题;

  • 减少大量的虚函数调用;

  • 将数据尽可能地从内存加载到Cache上;

  • LLVM做了很多自动矢量化的工作;

比如,下图左侧是通用代码,右侧是CodeGen之后的代码。CodeGen根据实际情况消除了不必要的循环和判断。

 图1 通用性处理逻辑和LLVM代码示意

另外,LLVM技术可以有不同的实现粒度。比如:可使用LLVM加速表达式计算,或再进一步,将多个算子融合编译成定制的机器码,或将自定义函数、存储过程等编译成定制的机器码。

 图2 LLVM的实现粒度

数据库在执行引擎中,运用LLVM技术提升SQL的执行速度。如下图所示:

图3  LLVM技术运用于执行引擎

LLVM适用场景

LLVM对所有类型的SQL都会有收益吗?

答案是否定的。

因为执行实时编译本身需要耗费一定的时间(简单表达式能做到毫秒级,复杂情况在百毫秒级),对于查询本身耗时较少的场景,加入LLVM反而会导致性能劣化。

因此,目前LLVM在OLAP/HTAP分析型业务场景中收益较大,有着广泛应用,而在OLTP交易型业务场景中,则相对没有那么广泛。

LLVM在OLTP中就一定没有收益吗?

答案同样是否定的。

找对场景,一样有收益。比如根据ISPRAS 2017年发表的实验结果(jit-compiling sql queries in postgresql using llvm)可知:pgbench测试下,OLTP场景中简单的查询加上JIT(Just-in-time及时编译,LLVM天然支持)扩展没有带来性能的提升,甚至将TPS(事务数/秒)从21.8降低到了7.8。

但是在Prepared query(plan cached)的情况下,和简单的查询相比,Plancache + CodeGen将TPS从21.8提升到了43,性能上有了约两倍的提升。

 

 图4 简单查询、CodeGen流程、Plancache和“Plancache +CodeGen”流程的性能对比

GaussDB中的LLVM

1. LLVM在华为应用于数据库的时间线

华为数据库在LLVM上的研究还是非常超前的。早在2015年,华为就作为PostgreSQL全球开发者大会的赞助商,在会上发表的动态编译(Go Faster with Native Compilation)演讲并引起了很大的反响。

当时社区领袖Josh Burkus在其博客里面,用一节篇幅专门详细介绍了华为动态编译的议题。

图5 2015年社区领袖Josh Burkus介绍华为的动态编译议题

2017年,华为在面向OLAP场景的数据库内核中突破了LLVM动态编译技术,并在运营商、金融证券等多个行业的POC项目中帮助客户提升数据处理性能,同时,在软件开发过程中充分模块化、通用化接口设计,将LLVM同年落地到面向OLTP的数据库设计中。

目前,GaussDB数据库对于LLVM也在不断地演进开发。

2. GaussDB LLVM实现简析

GaussDB针对列存(主要用于分析场景)、行存(主要用于交易场景)都实现了CodeGen。如下图所示,从代码模块层次来看:

1) GaussDB通过API接口层封装处理了LLVM环境、资源、基本元素等。

2) GaussDB在CodeGen层调用API接口进行了不同粒度的实现。

3) GaussDB在执行引擎侧根据情况使用CodeGen技术进行性能优化。

图6 GaussDB LLVM 模块层次图

GaussDB启动后会进行LLVM的初始化工作,检查CPU对CodeGen的支持情况,并进行环境初始化。

在执行启动阶段,以表达式为例,程序会判断当前表达式是否可JIT,是的话,则会进行IR函数的生成和生成定制机器码,及原本表达式执行函数的入口替代工作。

在实际执行过程中,运行处理函数(该函数已经在上一阶段进行了入口替代)进行实际执行工作。

在执行结束后的清理阶段,释放LLVM相关资源。

 图7 GaussDB CodeGen编译执行流程简图

GaussDB使用了阈值codegen_cost_threshold来估算当前查询使用LLVM技术是否能带来收益。如果处理数据的规模大于该阈值后,才会继续使用LLVM技术进行相关处理。该阈值代表行数,也可以理解成处理数据的规模,默认值为100000行,可以调节。

在OLAP场景中,GaussDB在判断是否能够对于一个算子进行CodeGen后(如:数据类型,算子类型判断等),开始生成对应的IR bytecode片段,之后MCJIT模块会调用生成的LLVM Module单元进行执行。

在OLTP场景中,GaussDB则会在Plan Cache场景下结合CodeGen框架,通过缓存机器码的方式,节省下编译生成中间语言IR Func以及优化成机器码的时间,整个过程是异步的。因此,在大量重复查询的场景下,后续的查询也会因为LLVM技术而受益。

另外,为了避免行数估计错误而选择CodeGen导致性能劣化,GaussDB还研发了当前业界独有的异步编译功能,即在查询语句确定要使用CodeGen的时候,将编译工作转交给后台线程,工作线程在JIT函数编译完成前继续使用原始执行逻辑执行,编译完成后,再替换成JIT函数执行。

3. GaussDB LLVM支持加速的场景

支持LLVM的表达式:

行存表达式计算支持的数据类型不受限制。

在向量化执行引擎中,仅当表达式出现在Scan节点的filter、Hash Join节点中的complicate hash condition, hash join filter, hash join target, Nested Loop节点中的filter, join filter, Merge Join节点的merge join filter, merge join target, Group节点中的filter表达式时,才会考虑是否使用LLVM动态编译优化。

在行执行引擎中,除一次性的表达式计算外,会考虑为所有算子的filter和Targetlist表达式都使用LLVM动态编译优化。

支持LLVM的算子:

Join :HashJoin(仅向量化执行引擎支持)

Agg :HashAgg

Sort(仅向量化执行引擎支持)

其中,HashJoin算子仅支持Hash Inner Join,对应的hash cond仅支持int4, bigint, bpchar类型的比较;HashAgg算子仅支持针对bigint, numeric类型的sum及avg操作,且group by语句仅支持int4, bigint, bpchar, text, varchar, timestamp类型操作,同时支持count(*)聚集操作。Sort算子仅支持对int4, bigint, numeric, bpchar, text, varchar数据类型的比较操作。除此之外,无法使用LLVM动态编译优化,具体可通过explain performance工具进行显示。

4. GaussDB LLVM使用建议

GUC参数:

enable_codegen:控制LLVM特性的打开和关闭。目前数据库内核侧默认打开。

codegen_cost_threshold:使用处理行数控制是否开启codegen,默认为10000。10000是通过实验验证得出的优化值,不建议将此值设置的过低。

另外,在开启LLVM特性的前提下,建议在允许的条件下尽可能设置较大的work_mem,如果出现大量下盘,则建议关闭LLVM动态编译优化。用户可通过analysis_options为on(LLVM_COMPILE),执行对应查询语句,在User Define Profiling中就可以看到LLVM的编译时间。结合此数据,可对codegen_cost_threshold进一步调整以获取更好的查询性能。

5. GaussDB LLVM性能表现

GaussDB实验室分别就codegen打开和关闭进行了TPCH性能测试。

表1 测试环境

测试结果显示,打开codegen时,带有qual的SQL,查询性能都有明显提升,且提升比例与qual在整个SQL中的占比相关,像Q6、Q12、Q19等qual占比较高的查询,性能提升也较多。

表2 TPCH 部分Query的测试结果

TPCC的性能提升并没有TPCH那么多,但据实验室数据,打开codegen后,tpmC提升了约7%。

PostgreSQL中的LLVM

1. LLVM在PostgreSQL应用的时间线

LLVM在PostgreSQL社区中的技术讨论开始的比较早:

2015年,上文提到的华为在PostgreSQL开发者大会上做的演讲;

2016年,PostgreSQL社区开始对JIT的实现进行了讨论;

2018年,PostgreSQL11中,第一次正式采用LLVM加速表达式计算。

2. PostgreSQL LLVM实现简析

如下图所示,和GaussDB相同,PostgreSQL执行引擎使用CodeGen技术做性能优化。针对表达式求值和元组分解为所需的属性集合两大性能瓶颈,做了可选的编译执行加速。

 图 8 PgSQL LLVM 模块层次图

PostgreSQL使用了三个参数来判断是否使用CodeGen优化:

jit_above_cost,表示超过多少cost 的查询才会使用JIT 功能。默认为100000,如果设置为-1 则关闭JIT。

jit_inline_above_cost,表示超过多少cost 的查询使用JIT 的inline 功能。默认为500000,-1则关闭inline 功能。

jit_optimize_above_cost,表示超过多少cost 的查询使用JIT 的optimization 功能。默认为500000,-1则关闭优化功能。

其中,后两个参数都需要设置得比jit_above_cost大,否则没有意义。这和GaussDB的使用数据集大小来控制是否开启CodeGen思想类似。

另外,PostgreSQL对于LLVM生成的字节码目前无法在plan cache中复用。这个功能的实现在PostgreSQL的中长期计划中。

3. PostgreSQL LLVM支持加速的场景

当前,PostgreSQL的JIT实现支持对表达式计算以及元组拆解的加速。

表达式计算被用来计算WHERE子句、target lists, aggregate聚合和projections投影。通过为每一种情况生成专门的代码来实现加速。

元组拆解是把一个磁盘上的元组转换成其在内存中表示的过程。通过创建一个专门针对该表布局和要被抽取的列数的函数来实现加速。

总结

华为和PostgreSQL关于LLVM特性的研究都起步很早,华为作为LLVM技术应用于数据库先驱者引领了PostgreSQL的技术发展。对于LLVM应用于数据库,GaussDB和PostgreSQL各有实现方法。GaussDB作为企业级数据库,对比PostgreSQL数据库,其实现特性多于PostgreSQL。

 欢迎小伙伴们交流~

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python zip()函数(将多个可迭代对象的元素配对,创建一个元组的迭代器)zip_longest()

文章目录 Python zip() 函数深入解析基本用法函数原型基础示例 处理不同长度的迭代器高级用法多个迭代器使用 zip() 与 dict()解压序列 注意事项内存效率:zip() 返回的是一个迭代器,这意味着直到迭代发生前,元素不会被消耗。这使得 zip() 特别…

浅谈SpringBoot配置文件

文章目录 一、配置文件作用二、配置文件分类三、SpringBoot内置的配置文件格式3.1、.properties3.1.1、.properties配置语法3.1.2、.properties读取方式 3.2、.yml/.yaml3.2.1、.yml配置语法3.2.2、.yml读取形式 四、两种配置文件优缺点4.1、.properties4.2、.yml4.2.1、.yml支…

多门店小程序如何给各个门店进行结算

​有些商家业务扩张,会开设多个门店。其中有些门店是直营,有些门店是加盟。如果用一个小程序来涵盖所有门店的业务,那将有助于商家进行统一管理和建立品牌效应。但如何给各个门店进行资金结算,是一个重要的问题,本文将…

探索JavaScript函数---基础篇

目录 函数 声明和调用 声明(定义) 调用 参数 形参和实参 形参(Formal Arguments) 实参(Actual Arguments) 形参与实参的关系 返回值 作用域 全局作用域 局部作用域 匿名函数 函数表达式 立…

无限可能LangChain——开启大模型世界

什么是大语言模型? 大语言模型是一种人工智能模型,通常使用深度学习技术(如神经网络)来理解和生成人类语言。这些模型拥有非常多的参数,可以达到数十亿甚至更多,使得它们能够处理高度复杂的语言模式。 我…

【网络安全】Web安全基础 - 第二节:前置基础知识- HTTP协议,握手协议,Cookie及Session

本章节主要介绍一些基础知识 d(^_^o) HTTP协议 什么是HTTP 超文本传输协议(HyperText Transfer Protocol)是一种用于分布式、协作式和超媒体信息系统的应用层协议。 HTTP是一个基于请求与响应,无状态的,应用层协议,…

30 分钟内掌握 Mainnet、Testnet 和 Devnet。Devnet是什么??

在区块链技术领域,Mainnet、Testnet 和 Devnet 等术语经常被使用,但也经常被误解。 这三种环境在区块链应用的开发和部署中起着至关重要的作用,但它们的区别和目的却常常被混淆。 让我们踏上探索之旅,揭开 Mainnet、Testnet 和 De…

HTML5+CSS3回顾总结

一、HTML5新特性 1.语义化标签 <header> 头部标签<nav> 导航标签<article> 内容标签<section> 定义文档某个区域<aside> 侧边栏标签<footer> 尾部标签 2.多媒体标签 2.1视频标签vedio 》常规写法&#xff08;尽量都使用mp4&#xff0…

google的chromedriver最新版下载地址

Chrome for Testing availability (googlechromelabs.github.io) 复制对应的地址跳转进去即可下载&#xff0c;下载前先看下自己google浏览器版本&#xff0c;找到对应的版本号去下载&#xff0c;把解压缩的exe放到google浏览器目录下。

3D软件开发的相关技术

3D开发涉及到广泛的技术和工具&#xff0c;涵盖了多个领域&#xff0c;包括计算机图形学、编程、设计、物理模拟等。以下是3D开发中常用的技术和工具&#xff0c;掌握这些技术需要广泛的知识和实践&#xff0c;项目的成功依赖于对这些技术的有效整合和应用。北京木奇移动技术有…

写大型C工程makefile构建~

正文 最开始学习linux应用开发编写的时候&#xff0c;估计大部分伙伴们都是在一个目录里面编译整个工程&#xff0c;主要是linux通常没有非常合适的集成开发环境。 以前单目录的方式实在太过捡漏&#xff0c;在linux环境中进行C代码工程开发很多时候需要编写一个相对比较通用的…

海康 面阵相机命名规则

海康 面阵相机命名规则 https://www.v-club.com/vCollage/vCollageDetail/516?subjectIdRMse6nPiyo

Nginx(openresty) 开启gzip压缩功能 提高web网站传输速度

1 开启nginx gzip压缩后&#xff0c;网页的图片&#xff0c;css、js等静态资源的大小会减少&#xff0c;节约带宽&#xff0c;提高传输效率&#xff0c;给用户快的体验,给用户更好的体验. 2 安装 #centos 8.5 yum install gzip 3 配置 #建议统一配置在http段 vim /usr/loca…

汇舟问卷:兼职做国外问卷三小时挣200

在繁忙的都市生活中&#xff0c;许多人为了生计而日夜奔波。对于大多数人来说&#xff0c;白天的工作已经足够充实&#xff0c;但依然有很多人选择在下班时间&#xff0c;多做些什么&#xff0c;为自己带来一份额外​的收入。 目前下班做的兼职工作不是跑滴滴&#xff0c;就是…

发表《Science Advances》!量子近似优化算法实现再突破

内容来源&#xff1a;量子前哨&#xff08;ID&#xff1a;Qforepost&#xff09; 文丨慕一/娴睿 排版丨沛贤 深度好文&#xff1a;1500字丨6分钟阅读 摘要&#xff1a;摩根大通、美国能源部&#xff08;DOE&#xff09;阿贡国家实验室和 Quantinuum 的研究人员证明了量子近似…

NetApp财季报告亮点:全闪存阵列需求强劲,云计算收入增长放缓但AI领域前景乐观

在最新的财季报告中&#xff0c;NetApp的收入因全闪存阵列的强劲需求而显著增长。截至2024年4月26日的2024财年第四季度&#xff0c;NetApp的收入连续第三个季度上升&#xff0c;达到了16.7亿美元&#xff0c;较前一年同期增长6%&#xff0c;超出公司指导中值。净利润为2.91亿美…

MySQL-事务日志

事务的隔离性由 锁机制 实现 事务的原子性、一致性、隔离性 由事务的 redo日志 和 undo 日志来保证 redo log 称为 重做日志&#xff0c;提供再写入操作&#xff0c;恢复提交事务修改的页操作&#xff0c;用来保证事务的持久性。undo log 称为 回滚日志&#xff0c;回滚行记录…

揭秘c语言作用域

前言 欢迎来到我的博客 个人主页:北岭敲键盘的荒漠猫-CSDN博客 本文主要整理c语言中 与作用域相关的知识点 本文适合对象:无编程基础&#xff0c;因为解释的比较多&#xff0c;所以不适合有基础的人快速掌握了 作用域描述 其实就是起作用的区域。比如个变量&#xff0c;函数…

System-Verilog 实现DE2-115倒车雷达模拟

System-Verilog 实现DE2-115倒车雷达模拟 引言&#xff1a; 随着科技的不断进步&#xff0c;汽车安全技术也日益成为人们关注的焦点。在众多汽车安全辅助系统中&#xff0c;倒车雷达以其实用性和高效性脱颖而出&#xff0c;成为现代汽车不可或缺的一部分。倒车雷达系统利用超声…

轻松拿捏C语言——【内存函数】

&#x1f970;欢迎关注 轻松拿捏C语言系列&#xff0c;来和 小哇 一起进步&#xff01;✊ &#x1f389;创作不易&#xff0c;请多多支持&#x1f389; &#x1f308;感谢大家的阅读、点赞、收藏和关注&#x1f495; &#x1f339;如有问题&#xff0c;欢迎指正~~ 目录&#x1…