StoneDB 源碼解讀系列文章正式開啟,預計以周更的形式跟大家見面,請多多支援~
StoneDB 采用基于知識網格技術和列式存儲引擎。該存儲引擎為海量資料背景下 OLAP 應用而設計,通過列式存儲資料、知識網格過濾、高效資料壓縮等特性,為應用系統提供低成本和高性能的資料查詢支援。
本文主要圍繞 StoneDB 引擎的查詢子產品,包括:查詢子產品結構圖、查詢流程、知識網格等展開。
StoneDB 架構圖
查詢子產品結構圖
SQL子產品(Query Layer)
- SQL Parser
解析器的主要作用是解析SQL語句,最終生成文法樹。解析器會對SQL語句進行文法和語義分析,如果有錯誤,則傳回相應的錯誤資訊。檢查通過後,解析器會查詢緩存,如果緩存中有對應的語句和查詢結果,則直接傳回結果,不進行接下來的優化和執行步驟。
- Optimizer
優化器的主要作用是對SQL語句進行優化,包括選擇合适的索引,資料的讀取方式,生成代價最小的執行計劃。
- Execute
執行器的主要作用是判斷操作的表是否有權限,如果有權限,會根據表的存儲引擎定義,調用接口去讀取資料,最後傳回滿足條件的查詢結果。
- Filter
粗糙集過濾,找到可能包含的包。
- DPN evaluation
根據DPN疊代判斷包裡面每條是否滿足。
- decompress
分片并行解壓粗糙過濾後命中的包。
知識網格子產品(Knowledge Grid)
知識網格是由資料包節點和知識節點組成的。由于資料包都是壓縮存放的,是以資料讀取解壓的代價比較高,在查詢中如何做到讀取盡量少的資料包是提升效率的關鍵。知識網格正是起到了這樣的一個作用,它能夠有效的過濾查詢中不符合條件的資料,以最小的代價定位以資料包為最小機關的資料。知識網格的資料大小隻占資料總量的1%以下,通常情況下可以加載到記憶體中,進一步提升查詢效率。
對于大部分統計、聚合性查詢,StoneDB 往往隻需要使用知識網格就能傳回查詢結果,這是因為通過知識網格可以消除或大量減少需要解壓的資料包,降低 IO 消耗,提高查詢響應時間和網絡使用率。例如:資料包節點記錄了最大值、最小值、平均值、總和、總記錄數、null 值的數量,如果想對某個列做聚合運算,那麼知識網格就能根據這些中繼資料很快的得到結果,而無需再解壓通路底層的資料包。
- 資料包節點(Data Pack Node)
資料包節點也稱為中繼資料節點(Metadata Node),因為資料包節點記錄了每個資料包中列的最大值、最小值、平均值、總和、總記錄數、null 值的數量、壓縮方式、占用的位元組數。每一個資料包節點對應一個資料包。
- 知識節點(Knowledge Node)
資料包節點的上一層是知識節點,記錄了資料包之間或者列之間關系的中繼資料集合,比如值資料包的最小值與最大值的範圍、列之間的關聯關系。大部分的知識節點資料是裝載資料的時候産生的,另外一部分是查詢的時候産生的。
查詢流程圖
查詢流程大緻步驟如下:
- Client 連接配接
與資料庫建立連接配接,此過程遵循 MySQL5.6、5.7 的連接配接協定。
- SQL Parser
對 SQL 語句進行文法和語義分析。
解析入口:
parse_sql()
- StoneDB Optimizer
對 SQL 語句進行優化,生成代價最小的執行計劃。
優化函數:
optimize_select()
- 知識網格
StoneDB 在執行查詢的時候會根據知識網絡(Knowledge Grid)把 DP 分成三類:
- 相關的 DP(Relevant Packs),滿足查詢條件限制的 DP
- 不相關的 DP(Irrelevant Packs),不滿足查詢條件限制的 DP
- 可疑的 DP(Suspect Packs),DP 裡面的資料部分滿足查詢條件的限制
入口函數:
RCAttr::ApproxAnswerSize
擷取DN:
Pack *get_pack(size_t i)
- 命中之後,解壓相關包。
主函數:
CprsErr Decompress
- 傳回結果集。
主函數:
ResultSender
知識網格
知識網絡總覽圖
知識網格由資料元資訊節點 (MD) 和知識節點 (KN) 組成, 通過知識網格,StoneDB 引擎無需通過傳統資料索引、資料分區、預測、手動調優或特定架構等方式就能高速處理複雜的分析查詢。
元資訊節點(MD)
資料元資訊節點 (MD) 與資料節點 (DN) 之間保持 1:1 關系,元資訊節點中包含了其對應資料塊中資料的相關資訊:
- 資料聚合函數值 (MIN,MAX,SUM,AVG 等)。
- 記錄數量 (count)。
- 資料中的 null 記錄标記。
- 元資訊節點在資料裝載的時候就會建構,MD 為資料壓縮, 聚合函數即席查詢等技術提供了支援。
- 知識節點 (KN) 除了基礎中繼資料外,還包括資料特征以及更深度的資料統計資訊。
- 知識網格存儲在記憶體中,友善快速查詢。
資料結構:
struct DPN{}
擷取DPN:
DPN &get_dpn
知識節點(KN)
Column Metadata 包含了該列的資料類型定義,限制條件等基礎資訊。
主類:
class impl
FieldRange 是一個辨別資料節點 (DN) 中記錄值範圍段的辨別 Map。針對數值類型的記錄 (date/time, integer,decimal…),FieldRange 可以用來快速确認目前對應 DN 是否包含所需資料。FieldRange 的組成:
- 從 MD 中擷取資料塊的 MAX 與 MIN,并将 MAX-MIN 劃分為固定段(例如1024)。
- 每個段中分别使用1個 bit 辨別是否有記錄存在于該範圍内。
Char Map 是一個記錄字元是否比對的 Map。針對字元類型的記錄(char,varchar等),CharMap 可以快速确定目前 DP 是否包含所需資料。
- 統計目前 DN 内,1-64 長度中 ASCII 字元是否存在的辨別值。
- 字元檢索時,按照字元順序,依次對比字元标示值即可知道該 DN 是否包含比對資料。
join nodes
- 在 Join 查詢時自動建立,以關系位圖的形式,存儲 Join 操作中關聯 DataNode 的資訊。
- 存儲在 Session 中,僅對目前 Client 生效。
- 顯著提高Join查詢性能。減少無效 DN 掃描,避免無用 IO 的産生。
distributions
- 統計目前 Column 中各記錄的值分布資訊。
- 基于統計資訊,和粗糙集 (RoughSet) 計算,提供近似查詢支援 (Approximate Query)。
以上是本文全部内容。