TiKV源码略读-Server Start
版權(quán)聲明:本文由神州數(shù)碼云基地團隊整理撰寫,若轉(zhuǎn)載請注明出處。
簡介TiKV啟動的主要流程,包括初始化配置-網(wǎng)絡(luò)端口沖突檢測-初始化文件系統(tǒng)-初始化Yet another thread pool-初始化加密-初始化raw engine v5.0-初始化engines-初始化GC-初始化Servers-初始化Services,最后啟動TiKV。時間隔的有點久,可以回顧一下上次的文章。上篇文章其實是整個server啟動過程中非常小的一部分,文章最后有一個整體流程圖可以點開看到左上角那一個黑點就是。
Jinn Jin:TiKV源碼略讀-Config?
這次我們的代碼略讀會基于v4.0.8這個分支開展閱讀工作,當閱讀完本次代碼之后,TiKV就真正運行起來了。TiKV服務(wù)啟動流程相關(guān)的代碼肯定擁有更多的邏輯細節(jié),我們會適當忽略一些細節(jié),以便集中在重要的幾個模塊邏輯上,避免過多的細節(jié)迷失方向。
主線流程:
和上一篇一樣,TiKV啟動主要流程我們還是用鏤空的圖示代表,每一步都會展開講解。
初始步驟:
初始步驟主要配置日志系統(tǒng)和環(huán)境變量檢查,沒有太多技術(shù)細節(jié),也不是我們重點關(guān)注的部分,所以我們先跳過。
?
初始化配置:
這部分的流程其實包含了上一篇文章內(nèi)容,都是配置信息的讀取,檢查和對應(yīng)的設(shè)置,不是主要的邏輯代碼,所以有幾塊內(nèi)容留著空白,等后續(xù)再補充。
?
網(wǎng)絡(luò)端口沖突檢測:
網(wǎng)絡(luò)地址和端口沖突檢測其實非常簡單,就是把配置中的地址和端口檢查一下可不可用,代碼量也不大,直接過。
初始化文件系統(tǒng):
?
這段代碼主要在store_path下新建了一個LOCK的文件,應(yīng)該是用來記錄和管理鎖相關(guān)的信息。然后會檢查現(xiàn)有的rocksdb文件是否正常,可用磁盤空間是否充足。
初始化Yet another thread pool:
這里調(diào)用了一個外部線程池管理庫,代碼就3行,看著只是配置了prometheus的監(jiān)控,貌似沒有更多實際的代碼邏輯。從github項目文件看,也是一個在完善中的庫。我們先對yatp有個初步的認識,等具體到項目中再看有沒有其他地方用到y(tǒng)atp。
tikv/yatp: Yet another thread pool in rust for both callbacks or futures. (github.com)
初始化加密:
?
通過配置文件初始化DataKeyManager,代碼就一行,很簡單。配置的時候會有幾個參數(shù)需要注意,一個是加密方法EncryptionMethod,包括了明文,AES128,AES192,AES256;還有一個是Master Key,可以通過明文,文件,access-key和secret-key三種方式配置。
pub enum EncryptionMethod {Unknown = 0,Plaintext = 1,Aes128Ctr = 2,Aes192Ctr = 3,Aes256Ctr = 4, }pub enum MasterKeyConfig {// Store encryption metadata as plaintext. Data still get encrypted. Not allowed to use if// encryption is enabled. (i.e. when encryption_config.method != Plaintext).Plaintext,// Pass master key from a file, with key encoded as a readable hex string. The file should end// with newline.#[serde(rename_all = "kebab-case")]File {#[serde(flatten)]config: FileConfig,},#[serde(rename_all = "kebab-case")]Kms {#[serde(flatten)]config: KmsConfig,}, }初始化raw engine v5.0:
這部分代碼是分支換成了master后梳理的內(nèi)容,當時感覺有點怪,但很明顯這部分代碼不屬于4.0版本,從最近的新分支可以看到這部分代碼是5.0的功能。
從代碼邏輯上看,這部分代碼可以通過config配置,設(shè)置當前節(jié)點使用本地rocksdb還是raft版本的engine,似乎有大的功能計劃,也可能是打算之后廢棄init_engines部分的代碼,這兩部分代碼有比較大的重疊部分。
而且raftengine也拉出去變成了一個新的項目庫,核心代碼會有比較大的變化,很期待。
初始化engines:
TiKV啟動流程里的核心代碼,第一部分會初始化兩個engine:
- raft_engine存儲在raftdb_path目錄內(nèi),應(yīng)該是給raft保存信息用的;
- kv_engine存儲在DEFAULT_ROCKSDB_SUB_DIR目錄內(nèi),是rocksdb所在的地方。
這兩個engine會組合在一起保存在engine::Engines里。之后會再初始化一個RaftKV的engine,這個engine的參數(shù)不是本地目錄,而是一個raft router,可以猜測應(yīng)該是node之間通信的engine。
初始化GC:
官網(wǎng)只有TiDB的GC相關(guān)文檔,并沒有過多關(guān)于TiKV的GC相關(guān)的內(nèi)容。從代碼中大致可以看出TiKV的GC可能是用來處理鎖的相關(guān)事務(wù),這里的懸念我們暫時擱置一下,會在后續(xù)文章中詳細探究。
初始化servers:
那個紅色的框其實和這部分代碼關(guān)系不大,所以被我移到初始化config的代碼塊里了,5.0之后這個紅框就沒有了。
這里根據(jù)前面幾步初始化的配置,生成了snap manager和raft storage兩個管理對象,再生成了server這個對象。
server和SSTimporter,split_check_worker又一起參與到node.start方法中,這時候服務(wù)器開始作為tikv分布式系統(tǒng)中的一個節(jié)點開始啟動,包括啟動raft store,連通PD并注冊,一些后端的worker開始schedule工作,rocksdb準備工作也開始執(zhí)行了。
到這步結(jié)束,tikv單一節(jié)點內(nèi)部的準備工作都已經(jīng)完成,就等外部數(shù)據(jù)請求接入開始工作了。
注冊services:
這里主要注冊了import,debug,diagnostic,deadlock,backup,cdc等一系列g(shù)RPC服務(wù),這些服務(wù)會在下一步啟動TiKV時候一一執(zhí)行。
啟動TiKV:
?
這里是啟動的最后一步,首先執(zhí)行上一步注冊的services,然后開始運行snap worker,并開始監(jiān)聽gRPC端口,最后輸出“TiKV is ready to serve”的日志,標志TiKV正式啟動成功!
之后還有一些監(jiān)控指標的配置和等待結(jié)束信號的代碼,這里就不細細描述了,有興趣的小伙伴可以直接翻閱tikv的代碼,相信剩下的部分應(yīng)該不是難事。
下一篇文章打算弄一個最小版本的key-value單機數(shù)據(jù)庫,能夠接受gRPC的請求,有點類似talent plan,不過會用rust直接上手。
Talent Plan
整體架構(gòu)圖:
對TiKV感興趣的同學也可以來看看我們組其他小伙伴(就是封面上的帥哥靚妹們)寫的學習筆記,喜歡的話可以點個贊:
數(shù)據(jù)庫實戰(zhàn)踩坑指南1:取前N項,需要WITH TIES
TiDB源碼學習筆記:制定計劃
TiDB源碼學習筆記:執(zhí)行計劃
神州數(shù)碼云基地
總結(jié)
以上是生活随笔為你收集整理的TiKV源码略读-Server Start的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。