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。

?歡迎小伙伴們交流~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/18693.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/18693.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/18693.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue項目出現多次ElMessage

問題: 解決方法: let message null if (message null) { message ElMessage.error(“登錄過期,請重新登錄”); } 最終效果:只出現一個彈框

Orange AIpro Color triangle幀率測試

OpenGL概述 OpenGL ES是KHRNOS Group推出的嵌入式加速3D圖像標準,它是嵌入式平臺上的專業圖形程序接口,它是OpenGL的一個子集,旨在提供高效、輕量級的圖形渲染功能。現推出的最新版本是OpenGL ES 3.2。OpenGL和OpenCV OpenCL不同,…

實操專區-第15周-課堂練習專區-漏斗圖與金字塔圖

實操專區-第15周-課堂練習專區-漏斗圖 下載安裝ECharts,完成如下樣式圖形。 代碼和截圖上傳 基本要求:下圖3選1,完成代碼和截圖 完成 3.1.3.16 漏斗圖中的任務點 基本要求:2個選一個完成,多做1個加2分。 請用班級學號姓…

銀行對公貸款軟件業務流程詳解

對公貸款業務是指商業銀行向企事業單位提供資金支持,用于資本擴充、生產經營、項目建設等方面的融資。其目的在于支持企事業單位的發展,推動經濟增長。通過提供資金支持,企事業單位可以獲得必要的資金來擴大生產規模、提高生產能力、研發新產…

第8周 分布式事務與數據一致性主流解決方案落地

第8周 分布式事務與數據一致性主流解決方案落地 1. 最終一致性原理與解析2. 微服務的解耦3. 本地消息存儲4. 自定義事務管理器5. 本地消息刪除********************************************************************************** 本周拓展數據的一致性落地,采用弱…

【Java EE】網絡原理——HTTP請求

目錄 1.認識URL 2.認識“方法(method)” 2.1GET方法 2.1.1使用Fiddler觀察GET請求 2.1.2 GET請求的特點 2.2 POST方法 2.2.1 使用FIddler觀察POST方法 2.2.2 POST請求的特點 3.認識請求“報頭”(header) 3.1 Host 3.2 C…

Spring MVC 工作流程源碼分析

前言: 我們知道 Spring MVC 的核心是前端控制器 DispatcherServlet,客戶端所有的請求都會交給 DispatcherServlet 來處理,本篇我我們來分析 Spring MVC 處理客戶端請求的流程,也就是工作流程。 Sping MVC 只是儲備傳送門&#x…

Java整合EasyExcel實戰——3(上下列相同合并單元格策略)

參考&#xff1a;https://juejin.cn/post/7322156759443095561?searchId202405262043517631094B7CCB463FDA06https://juejin.cn/post/7322156759443095561?searchId202405262043517631094B7CCB463FDA06 準備條件 依賴 <dependency><groupId>com.alibaba</gr…

鄰接矩陣廣度優先遍歷

關于圖的遍歷實際上就兩種 廣度優先和深度優先&#xff0c;一般關于圖的遍歷都是基于鄰接矩陣的&#xff0c;考試這些&#xff0c;用的也是鄰接矩陣。 本篇文章先介紹廣度優先遍歷的原理&#xff0c;和代碼實現 什么是圖的廣度優先遍歷&#xff1f; 這其實和二叉樹的層序遍…

新人學習筆記之(數組1)

一、數組的概念 1.數組&#xff08;Array&#xff09;可以把一組相關的數據一起存放&#xff0c;并提供方便的訪問&#xff08;獲取&#xff09;方式 2.數組是指一組數據的集合&#xff0c;其中的每個數據被稱作元素&#xff0c;在數組中可以存放任意類型的元素&#xff0c;數組…

數據結構——二叉樹的基本應用

在此之前我們已經初步了解了二叉樹&#xff0c;在介紹堆的基本應用時&#xff0c;我們已經具體介紹了完全二叉樹的基本應用&#xff0c;本章我們介紹二叉樹的基本應用&#xff0c;這個不止指的是完全二叉樹&#xff0c;而是指泛型的二叉樹。 二叉樹的基本應用&#xff0c;由于…

代碼隨想錄算法訓練營第54天|● 392.判斷子序列 ● 115.不同的子序列

392. 判斷子序列 這個微軟面試的時候考過 雙指針就行 編輯距離入門題&#xff1a; 思路是一樣的 相同字符1 否則從前面順下來 class Solution:def isSubsequence(self, s: str, t: str) -> bool:dp[[0]*(len(t)1) for _ in range(len(s)1)]for i in range(1,len(s)1):f…

aspose-*的使用

文章目錄 aspose-*一、依賴--maven二、需求1、word------>pdf2、doc------>docx2、xls------>xlsx aspose-* 一、依賴–maven 備注&#xff1a;第三方的jar包可以從資源中下載&#xff0c;有上傳的 <!--aspose依賴--><dependency><groupId>aspose…

刷代碼隨想錄有感(81):貪心算法——分發餅干

題干&#xff1a; class Solution { public:int findContentChildren(vector<int>& g, vector<int>& s) {sort(g.begin(), g.end());sort(s.begin(), s.end());int index s.size() - 1;int res 0;for(int i g.size() - 1; i > 0; i--){if(index >…

GitLab項目中添加用戶,并設置其角色權限等

注意&#xff1a;創建用戶(new user)&#xff0c;創建完用戶然后再項目邀請用戶&#xff0c;選擇創建過的用戶 一、以管理員身份登錄GitLab的WebUI并創建用戶 1>.使用管理員登錄GitLab 使用管理員(root)用戶登錄成功后&#xff0c;點擊如下圖所示的小扳手&#xff0c;點擊…

java 反射的用法

下面是一個簡單的Java反射示例&#xff0c;演示了如何使用反射機制獲取類的信息并調用其方法&#xff1a; import java.lang.reflect.Method;class MyClass {private String name;public void setName(String name) {this.name name;}public String getName() {return name;}…

C++數據結構之:鏈List

摘要&#xff1a; it人員無論是使用哪種高級語言開發東東&#xff0c;想要更高效有層次的開發程序的話都躲不開三件套&#xff1a;數據結構&#xff0c;算法和設計模式。數據結構是相互之間存在一種或多種特定關系的數據元素的集合&#xff0c;即帶“結構”的數據元素的集合&am…

在HTML和CSS當中運用顯示隱藏

1.顯示與隱藏 盒子顯示:display:block;盒子隱藏: display:none:隱藏該元素并且該元素所占的空間也不存在了。 visibility:hidden:隱藏該元素但是該元素所占的內存空間還存在&#xff0c;即“隱身效果”。 2.圓角邊框 在CSS2中添加圓角&#xff0c;我們不得不使用背景圖像&am…

學習筆記——數據通信基礎——數據通信網絡(網絡工程師)

網絡工程師 網絡工程&#xff0c;就是圍繞著網絡進行的一系列的活動&#xff0c;包括∶網絡規劃、設計、實施、調試、排錯等。網絡工程設計的知識領域很寬廣&#xff0c;其中路由和交換是計算機網絡的基本。 網絡工程師∶是在網絡工程領域&#xff0c;掌握專業的網絡技術&…

散戶如何參與期權交易?

期權就是股票&#xff0c;唯一區別標的物上證指數&#xff0c;會看大盤吧&#xff0c;期權交易兩個方向認購做多&#xff0c;認沽做空&#xff0c;雙向t0交易沒了&#xff0c;期權交易跟期貨一樣&#xff0c;對的&#xff0c;玩的也是合約&#xff0c;唯一區別沒有保證金不會爆…