万物互联的态势下,数据量的激增使得“如何提升数据处理性能”成为各家数据库共同面临的挑战。作为编译优化技术的代表,基于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)的情况下,叠加 JIT技术之后将TPS从20.7提升到了43,性能上有了两倍的提升。
▲ 图4 简单查询、CodeGen流程、Plancache和“Plancache +CodeGen”流程的性能对比
总结
LLVM被广泛运用于数据库、大数据、AI等领域。在数据库领域,多家商业数据库和开源数据库都应用其加速数据库处理。GaussDB作为企业级的数据库,经过了多年的技术发展,具备丰富的技术特性,使用该技术后提升了系统的查询性能,使得客户在OLAP和OLTP多场景中均受益。
来源:华为云社区
GaussDB学习地址:bbs.huaweicloud.com/blogs/42818…