隨著資料庫軟硬體技術的發展,經典的 SQL 計算引擎逐漸成為資料庫系統的效能瓶頸,尤其是對於涉及到大量計算的 OLAP 場景。
如何充分發揮底層硬體的能力,提升資料庫系統的效能,成為近年來資料庫領域的熱門研究方向,而向量化執行就是解決上述問題的一種有效手段,本文主要對向量化技術的原理及優點進行簡單的介紹。
為什麼資料庫需要向量化?
MPP資料庫的API(Application Programming Interface)或者命令列接收到了SQL查詢請求之後,系統先經過查詢解析,然後進行查詢最佳化,透過任務排程執行從儲存引擎裡面把資料讀取出來,計算出結果集,返回給客戶。
一個查詢語句經過詞法分析、語法分析、語義檢查後生成的結果叫做Query Tree,經過最佳化器之後的結果叫做Plan Tree。
傳統資料庫執行查詢計劃通常採用火山模型的方式,流程如上圖所示。
火山模型具有簡單、直觀、易用等優點,早期資料庫受限於硬體水平,IO、記憶體和CPU資源都非常昂貴,火山模型能夠極大縮減記憶體使用量,因而被各大廠商普遍採用。
如今,隨著硬體技術的不斷髮展,火山模型的弊端也逐漸凸顯。這種方式存在重複性執行多、反序列化代價高、資料區域性性差等缺陷,而且一次執行僅處理一行資料,CPU花費大量時間在遍歷查詢操作樹上,同時也沒有針對CPU的SIMD能力等特性做最佳化,從而造成查詢執行效率低下的問題。
據我們在PostgreSQL上實際測試,對於select sum(a) from table這樣的查詢,火山模型在執行查詢計劃時,大部分時間用於讀取資料、對資料的反序列化、遍歷執行樹等操作上,用於實際SUM運算的時間不足4%。
為了進一步提升SQL計算引擎的效能,資料庫執行器領域出現向量化和編譯執行的新技術。這兩種技術的出現都是為了提升效能,更準確地講是為了提升 CPU的執行效能。
編譯執行是把複雜運算編譯成一個函式,重複呼叫得到結果。編譯執行的優點是可以減少分支判斷,並使函式呼叫棧變淺。
向量化執行指的是將一次計算一條元組的形式,轉換為一次計算多條元組的向量化計算。透過實現批次讀取和處理,大大精簡了函式呼叫開銷,減少了重複運算,增加了資料的區域性性,提高了執行效率。
HashData向量化的實踐
對於像HashData這樣採用雲架構的資料倉儲而言,向量化可以透過提升單節點的執行能力,使整個叢集的運算效能得到很大提升。列存資料的高壓縮比不僅節約了儲存空間,同時在向量化運算過程中也有著天然的效能優勢。
HashData在實現向量化的過程中,引入了Apache 軟體基金會開源專案Apache Arrow。Arrow 定義了標準的方式來表示可有效處理的記憶體資料,同時支援多種流行的程式語言中,包括 Java、C、C++ 和 Python等。
Apache Arrow的子專案Gandiva提供了編譯執行向量化運算的可能,在應用於資料庫表示式計算時,相對於解釋執行的向量化運算也有明顯的效能優勢,但是由於百毫秒量級的編譯時間,不利於小資料量查詢,因此需要在最佳化階段根據資料情形決定是否使用。
為確保分散式資料庫的底層資料的穩定傳輸,Arrow提供了基於gRPC的程式間通訊Flight,其允許資料以Batch的形式同時進出伺服器叢集,讓開發人員可以更輕鬆地建立可擴充套件的資料服務。
根據我們在PostgreSQL單機測試的結果,在使用Arrow做向量化執行後,ORC資料格式+向量化,相對於heap表加+行引擎,在最好的情形下可以獲得30倍以上的資料效能提升。
資料庫的向量化不僅僅是資料儲存和運算的向量化,還是一個巨大的效能最佳化工程。未來,HashData會持續最佳化、完善向量化執行,提升系統效能,更好地滿足客戶業務需求。