TiDB 源碼閱讀系列文章(二)源碼架構介紹

TiDB 源碼閱讀系列文章(二)源碼架構介紹

來自專欄 DB Notes

第一篇文章介紹整體的架構,知道 TiDB 有哪些模塊,分別是做什麼的,從哪裡入手比較好,哪些可以忽略,哪些需要仔細閱讀。

這篇文章是一篇入門文檔,難度係數比較低,其中部分內容可能大家在其他渠道已經看過,不過為了內容完整性,我還是會放在這裡。

TiDB 架構

本次 TiDB 源碼之旅從這幅簡單的架構圖開始,這幅圖很多人都看過,我們可以用一句話來描述這個圖:『TiDB 是一個支持 MySQL 協議,以某種支持事務的分散式 KV 存儲引擎為底層存儲的 SQL 引擎』。從這句話可以看出有三個重要的事情,第一是如何支持 MySQL 協議,與 Client 交互,第二是如何與底層的存儲引擎打交道,存取數據,第三是如何實現 SQL 的功能。本篇文章會先介紹一些 TiDB 有哪些模塊及其功能簡要介紹,然後以這三點為線索,將這些模塊串聯起來。

代碼簡介

TiDB 源碼完全託管在 Github 上,從項目主頁可以看到所有信息。整個項目使用 Go 語言開發,按照功能模塊分了很多 Package,通過一些依賴分析工具,可以看到項目內部包之間的依賴關係。

大部分包都以介面的形式對外提供服務,大部分功能也都集中在某個包中,不過有一些包提供了非常基礎的功能,會被很多包依賴,這些包需要特別注意。

項目的 main 文件在 tidb-server/main.go,這裡面定義了服務如何啟動。整個項目的 Build 方法可以在 Makefile 中找到。

除了代碼之外,還有很多測試用例,可以在 xx_test.go 中找到。另外 cmd 目錄下面還有幾個工具包,用來做性能測試或者是構造測試數據,其中的 benchkv 以及 benchraw 可以當做 TiKV 的 go client 使用示例

模塊介紹

從哪裡入手

粗看一下 TiDB 有 80 個包,讓人覺得無從下手,不過並不是所有的包都很重要,另外一些功能只會涉及到少量包,從哪裡入手去看源碼取決於看源碼的目的。

如果是想了解某一個具體的功能的實現細節,那麼可以參考上面的模塊簡介,找到對應的模塊即可。

如果是相對源碼有全面的了解,那麼可以從 tidb-server/main.go 入手,看 tidb-server 是如何啟動,如何等待並處理用戶請求。再跟著代碼一直走,看 SQL 的具體執行過程。另外一些重要的模塊,需要看一下,知道是如何實現的。輔助性的模塊,可以選擇性的看一下,有大致的印象即可。

重要模塊

在全部 80 個模塊中,下面幾個模塊是最重要的,希望大家能仔細閱讀,針對這些模塊,我們也會用專門的文章來講解。

  • plan
  • expression
  • executor
  • distsql
  • store/tikv
  • ddl
  • tablecodec
  • server
  • types
  • kv
  • session

輔助模塊

除了重要的模塊之外,餘下的是輔助模塊,但並不是說這些模塊不重要,只是鎖這些模塊並不在 SQL 執行的關鍵路徑上,我們也會用一定的篇幅描述其中的大部分包。

SQL 層架構

這幅圖比上一幅圖詳細很多,大體描述了 SQL 核心模塊,大家可以從左邊開始,順著箭頭的方向看。

Protocol Layer

最左邊是 TiDB 的 Protocol Layer,這裡是與 Client 交互的介面,目前 TiDB 只支持 MySQL 協議,相關的代碼都在 server 包中。

這一層的主要功能是管理客戶端 connection,解析 MySQL 命令並返回執行結果。具體的實現是按照 MySQL 協議實現,具體的協議可以參考 MySQL 協議文檔。這個模塊我們認為是當前實現最好的一個 MySQL 協議組件,如果大家的項目中需要用到 MySQL 協議解析、處理的功能,可以參考或引用這個模塊。

連接建立的邏輯在 server.go 的 Run() 方法中,主要是下面兩行:

236: conn, err := s.listener.Accept()

258: go s.onConn(conn)

單個 Session 處理命令的入口方法是調用 clientConn 類的 dispatch 方法,這裡會解析協議並轉給不同的處理函數。

SQL Layer

大體上講,一條 SQL 語句需要經過,語法解析-->合法性驗證-->制定查詢計劃-->優化查詢計劃-->根據計劃生成查詢器-->執行並返回結果 等一系列流程。這個主幹對應於 TiDB 的下列包:

KV API Layer

TiDB 依賴於底層的存儲引擎提供數據的存取功能,但是並不是依賴於特定的存儲引擎(比如 TiKV),而是對存儲引擎提出一些要求,滿足這些要求的引擎都能使用(其中 TiKV 是最合適的一款)。

最基本的要求是『帶事務的 Key-Value 引擎,且提供 Go 語言的 Driver』,再高級一點的要求是『支持分散式計算介面』,這樣 TiDB 可以把一些計算請求下推到 存儲引擎上進行。

這些要求都可以在 kv 這個包的[介面]中找到,存儲引擎需要提供實現了這些介面的 Go 語言 Driver,然後 TiDB 利用這些介面操作底層數據。

對於最基本的要求,可以重點看這幾個介面:

  • Transaction:事務基本操作
  • Retriever:讀取數據的介面
  • Mutator:修改數據的介面
  • Storage:Driver 提供的基本功能
  • Snapshot:在數據 Snapshot 上面的操作
  • Iterator:Seek 返回的結果,可以用於遍曆數據
  • 有了上面這些介面,可以對數據做各種所需要的操作,完成全部 SQL 功能,但是為了更高效的進行運算,我們還定義了一個高級計算介面,可以關注這三個 Interfce/struct :
  • Client:向下層發送請求以及獲取下層存儲引擎的計算能力
  • Request: 請求的內容
  • Response: 返回結果的抽象

小結

至此,讀者已經來了解了 TiDB 的源碼結構以及三個主要部分的架構,更詳細的內容會在後面的章節中詳細描述。


推薦閱讀:

TiDB RC4 Release
TiDB 在零氪科技(LinkDoc)大數據醫療系統的實踐
TiDB 1.1 Beta Release
oceanbase、TiDB這類NewSQL最近勢頭好強勁,它們的定位究竟是什麼?
TiDB能否覆蓋HBase的絕大多數使用場景?

TAG:分散式資料庫 | TiDB | 開源 |