做者: Shirly網絡
本文將簡要介紹 TiKV Coprocessor 的基本原理,面向想要了解 TiKV 數據讀取執行過程的同窗,同時也面向想對該模塊貢獻代碼的同窗。閱讀本文前,建議讀者對 TiDB 總體架構有所瞭解,先閱讀三篇文章瞭解 TiDB 技術內幕:說存儲、說計算、談調度。架構
熟悉 TiDB 總體框架 的同窗可能記得,TiDB 是無狀態的,數據存儲在 TiKV 層。當 TiDB 在收到一個來自客戶端的查詢請求時,會向 TiKV 獲取具體的數據信息。那麼一個讀請求最樸素的處理過程以下:框架
首先須要確定的是這種方式當然能解決問題,可是性能如何呢?咱們來一塊兒分析一下:異步
看到以上問題後,聰明如你,可能很容易就想到,能不能讓 TiKV 把本身負責的那部分數據作一次計算,再返回給 TiDB 呢?函數
有何不可呢?性能
TiKV 讀取數據並計算的模塊,咱們定義爲 Coprocessor,該概念靈感來自於 HBase,目前在 TiDB 中的實現相似於 HBase 中的 Coprocessor 的 Endpoint 部分,也可類比 MySQL 存儲過程。優化
有了 Coprocessor 後,從宏觀看一個讀請求是如何下發到 TiKV 的呢?如下面的請求爲例:spa
如圖,以上查詢語句在 TiDB 中處理以下:線程
TiKV Coprocessor 處理的讀請求目前主要分類三種:3d
那麼 TiKV 在收到 Coprocessor 請求後,什麼時候區分這三種請求的呢?
請求到了 TiKV 層,處理過程以下:
目前 Coprocessor 支持的三種接口中,後面兩種接口相對比較簡單,而 DAG 是裏面最複雜也是最經常使用的,因此本文後續將重點介紹 DAG 類請求。
DAG 顧名思義,是由一系列算子組成的有向無環圖,算子在代碼中稱爲 Executors。
目前 DAG 請求主要實現了兩種計算模型:
在目前的 TiKV master 上,處於火山模型向向量化模型的過分階段,於是兩種計算模型同時存在。TiKV 收到請求時,會優先檢測是否可走向量化模型,若部分功能在向量化模型中沒有實現,則走舊的計算模型,具體處理邏輯流程以下:
相關代碼在:src/coprocessor/dag/mod.rs
。
由於火山模型已在被棄用中,因此下文咱們只講向量化計算模型。
在向量化計算模型中,全部算子都實現了 BatchExecutor
接口,其主要定義了一個 get_batch
的函數:
pub trait BatchExecutor: Send { fn next_batch(&mut self, scan_rows: usize) -> BatchExecuteResult; } pub struct BatchExecuteResult { pub physical_columns: LazyBatchColumnVec, pub logical_rows: Vec<usize>, pub is_drained: Result<bool, Error>, ... }
參數說明:
next_batch
中 scan_rows
由上層控制,因爲掃的數據過多會慢,所以該數字從 32 倍增到 1024。BatchExecuteResult
中,因爲返回了一批空數據不表明全部數據都處理完畢了,例如可能只是全被過濾,於是使用單獨字段表示全部數據處理完畢。目前 TiKV 支持的算子主要有如下幾類。
components/tidb_query/src/batch/executors/table_scan_executor.rs
select col from t
components/tidb_query/src/batch/executors/index_scan_executor.rs
select index from t
components/tidb_query/src/batch/executors/selection_executor.rs
select col from t where a+b=10
components/tidb_query/src/batch/executors/limit_executor.rs
select col from t limit 10
components/tidb_query/src/batch/executors/top_n_executor.rs
select col from t order by a+1 limit 10
components/tidb_query/src/batch/executors/*_aggr_executor.rs
select count(1) from t group by score + 1
綜上,各個算子之間能夠按照如下方式任意組合,以下圖所示:
案例:select count(1) from t where age>10
因爲篇幅緣由,本文只是講了一些 Coprocessor 的概要,讀者對此有個概念便可。後續咱們將推出該模塊相關的更多更深的源碼細節分析,歡迎你們繼續閱讀並給出建設性的改進意見。
原文閱讀:https://pingcap.com/blog-cn/tikv-source-code-reading-14/