鯤鵬BoostKit OminiRuntime:高效的數據Runtime底座
分析引擎在為企業提供低延遲和低成本的實時分析方面發揮著至關重要的作用。隨著數據規模和多樣性爆炸式增長,企業應用要求分析系統具備高并發查詢和高吞吐,同時支持對結構化和非結構化數據的查詢。
為了滿足這些要求,分析引擎和數據庫通常依賴于將查詢計劃編譯為本機代碼。手動編寫算子的方式,如filter,join和group by,通常包含處理不同參數和數據類型所需的控制流。本機代碼生成的目的是通過消除不必要的代碼并將其專門用于底層平臺,從而最大限度地減少指令數量。
然而,上述方案在易用性和硬件兼容性方面往往存在局限性,我們總結為三點:
1. 數據獲?。簺]有有效的方法過濾非必要的數據,大量計算資源被浪費
2. 數據計算:算子通過JAVA、Scala等高級語言實現,無法充分發揮算力;算子優化困難
3. 數據層優化:要解決端到端流程中的問題,各個引擎需要做垂直優化
為此,鯤鵬應用使能套件BoostKit中提供了大數據的Runtime底座——OmniRuntime, 通過五個核心組件,如下圖所示,實現針對數據接入、傳輸、計算全周期開展性能優化,提升大數據分析場景的性能提升30%以上。
圖. 大數據的Runtime底座——OmniRuntime
圖. OmniRuntime核心組件示意圖
●OmniJit:一個透明、易于使用的即時編譯框架,不需要對任何低級代碼生成框架(如LLVM或Janino)的了解。
●OmniVec:一種列式內存格式,提供高性能內存訪問、全內存生命周期管理和內置SIMD操作。它還支持所有常用的數據類型,如int、double、varchar和decimal等。
●OmniOperator:native 算子庫,充分利用當今異構計算環境中可用硬件的計算能力,與OmniJit結合使用時,能夠動態地適應工作負載、參數和數據配置文件,以實現最佳性能。
●OmniCache:一種關系型緩存,性能優于傳統的面向塊的緩存,命中率極高。
●OmniData:快速數據訪問和協作層,提供數據層和計算層之間的雙向通信和數據傳輸。
1 OmniJit
OmniJit組件對分析工作負載的整體性能提高做出了重大貢獻。
OmniJit旨在為普通開發人員提供即時編譯支持。它提供了一個易于使用的高級語言框架,如C/C++。OmniJit自動識別運算符中最關鍵的性能代碼部分并優化它們。生成的運算符是專門使用查詢、運行時和硬件特定的計算機代碼的。OmniJit依賴于運行時信息來基于查詢上下文應用最佳優化。這可以是數據集基數、列大小、數據類型、可用硬件(SIMD、加速器等)以及許多其他信息,以產生最佳運算符優化。
通過使用OmniJit,分析引擎開發人員將不再需要與LLVM或Janino等系統提供的復雜低級API交互,以提取最佳性能。
圖2. OmniJit分支裁剪和循環展開優化
2 OmniOperator
OmniOperator表示處理特定查詢數據的計算邏輯代碼。SQL查詢可以由許多不同的算子組成,OmniJit負責動態優化它們。OmniJit優化了C++算子,以生成具有最小執行指令計數的可執行文件。
算子接口的結構與火山模型相似,因為它遵循類似的接口生命周期:實例化、AddInput、GetOuput和Close。所有OmniOperators都提供相同的標準接口,實現對分析引擎不透明。
通過利用標準接口,我們可以輕松地將這些運算符暴露給上層計算引擎。此外,它還幫助我們提供一致的開發生命周期體驗,同時允許跨各種分析平臺的可移植性。開發人員可以讓OmniJit使用自動化方法優化運算符?;蛘?,他可以指導優化策略,如參數固定、循環開發和代碼中特定核心方法的矢量化自適應執行。
與本機平臺運算符相比,生成的OmniOperators執行的指令計數更少,資源消耗更低,開發開銷也更低。下圖顯示了Java Analytics平臺中的整體OmniOperator生命周期。由于大多數分析引擎都是用Java編碼的,我們還提供了一個JNI接口來促進集成。
圖3. OmniOperator引擎與Native Operator的交互
3 OmniVector
OmniVector是OmniRuntime的另一個組件。OmniVector定義了標準的列式內存格式。OmniVector設計為可移植的、獨立于列的內存數據格式。OmniVector支持豐富的數據類型系統,旨在滿足各種分析數據系統的需求。這種內存數據格式為數據密集型應用程序提供高性能和高可擴展性。
OmniVector的核心代碼是在C++中實現的,帶有高級語言綁定,以實現交叉兼容性。它提供了一個異步接口,允許讀取和寫入操作由各種組件并行進行。這允許我們在寫入或持久化操作被繼續時公開OmniVector的內容。
下圖顯示了OmniVec的整體架構。
圖4. OmniVec Binging和Native架構
基于作用域的全生命周期管理的OmniVector不僅消除了內存泄漏的可能性,而且提供了高性能的內存訪問。每個OmniVector在其生命周期中都會經歷幾個步驟。每個步驟都由OmniVctor操作觸發:
1. 作用域創建:為了進行有效的內存管理并避免頁面故障開銷,向量在特定的執行作用域內分配。這允許高效的內存池,從而最大限度地減少內存管理開銷。
2. OmniVector分配:通過使用上面創建的范圍,開發人員現在可以分配新的向量。
3. OmniVector 修改:API支持Set和Put操作。前者在特定對應的索引位置操作單個值。后者是批處理put方法,在該方法中,數組插入到指定的開始位置。
4. OmniVector讀?。号c修改一樣,我們支持單值檢索或批處理操作。
5. OmniVector釋放:一旦不使用向量,就可以將其釋放到作用域內存池
6. 作用域釋放:釋放所有向量后,我們可以釋放作用域和關聯的內存池。
由于此設計,OmniVector支持以下功能:
●零拷貝操作
●支持數據生命周期管理和內存泄漏檢測。
●支持復雜的數據結構,如MAP、列表和結構。
●SIMD指令優化和硬件加速接口
●自動溢出到存儲
●高性能內存分配和池化。
4 OmniJit、OmniVctor和OmniOperator性能數據
我們在openLooKeng、Spark和Hive等流行的大數據系統中集成了OmniRuntime和OmniJit。然后,我們使用TPC-H在openLooKeng上進行了基準測試,實驗結果表明集成了Omniruntime框架的性能明顯優于原始分析引擎。
圖5. OmniJit優化的算子效果
5 OmniCache
OmniCache是OmniRuntime中的關系型緩存。OmniCache不僅緩存數據,還維護數據與緩存中的數據之間的關系。OmniCache構造虛擬數據集,緩存從物理集數據或其他虛擬數據集派生的關系數據,并使用SQL SELECT語句定義用于緩存的關系數據。
這種方法比傳統的基于文件塊的緩存系統具有優勢。傳統緩存系統中整個文件塊必須緩存或丟棄,這可能會導致許多數據換入和換出操作,導致緩存命中率非常低。
為了維護關系信息,OmniCache將其狀態和結構信息提供給查詢優化器,以最大限度地提高命中率。公開的緩存元數據有助于分析引擎優化查詢計劃,并首先訪問緩存中的數據,而不是通過慢速數據存儲。此外,緩存還能夠存儲中間查詢結果。它允許通過使查詢計劃程序直接訪問先前計算的數據,而不是執行如圖6所示的完整查詢計劃來加速操作。
圖6. OmniCache
Omnicache具備以下功能:
●緩存管理:通過使用物化視圖命令生成和管理物化視圖。
●SQL重寫:SQL重寫使用關系代數和成本模型執行,以有效利用緩存數據。
●緩存存儲:全局內存池的關系型緩存,基于堆外內存實現,可進行高效的數據存儲和訪問。
6 OmniData
OmniData是OmniRuntime的快速數據訪問和協作層,旨在減少數據存儲層和計算層之間的數據傳輸,這在現代存算分離的數據中心中非常有效。
OmniData不會直接從存儲端加載文件,然后處理數據,而是將特定操作卸載到存儲端進行近數據處理。目標是減少所需的網絡通信量和整體計算量。
OmniData通過將查詢執行劃分為幾個與數據分布匹配的階段來實現這一目標。然后,代表子處理操作的每個階段都被發送到存儲節點附近或存儲節點上執行。親和性調度用于避免存儲節點計算能力過載,并保持較高的整體吞吐量。階段性操作允許本地數據加載和處理。
圖. OmniData實現原理
未來展望
OmniRuntime使用OmniJit、OminVector、OmniOperator、OmniCache和OmniData的組合,為分析平臺提供通用的數據處理基礎,為不同分析引擎提供具有上下文優化功能的通用引擎,顯著減輕創建自定義優化的負擔,并支持異構硬件環境。
OmniRuntime持續提供強大的數據處理能力,使數據分析引擎能夠滿足高并發、高吞吐量、結構化和非結構化查詢的業務需求。未來,OmniRuntime將繼續聚焦更多的功能實現,如decimal類型支持、UDF框架、表達式優化,以及實現向量化優化等。
歡迎大家登錄hikunpeng.com——鯤鵬社區鯤鵬BoostKit專區了解更多關于OmniRuntime的詳細信息。