作者:沈泰寧 唐劉

許多人眼中的 PingCAP Talent Plan 可能就是 github.com/pingcap/tale 這個項目,但從內容角度來說並不完整,這個 Repo 只是線上課程的內容,我們還有與其配套的線下課程。

本文將從課程設計的角度和大家聊一聊 PingCAP Talent Plan(TiKV 方向)課程,包括課程設計的邏輯、課程設計中遇到的困難,以及大家在學習過程中常見的問題和解答等。

PingCAP Talent Plan 是什麼?

TiDB 是一個新型的開源分散式關係型資料庫,目標是希望在大數據和雲時代的新的業務需求下,幫助大家更好地解決數據大規模存儲和實時計算的問題。我們聽說很多同學跟我們反映他們很想參與到這些項目中去,但遇到了一些問題:

  • 編程語言是參與項目的敲門磚。Golang 和 Rust 都比較新,需要一定的學習,是最直接的高門檻。
  • 理論知識是深度參與的基礎。從理論到實踐有一道鴻溝,並不是這麼容易跨越。

為瞭解決上述問題,我們啟動了 PingCAP Talent Plan。目前課程主要分為兩個方向,面向 SQL 優化器、分散式計算的 TiDB 方向,和麪向大規模、一致性的分散式存儲的 TiKV 方向。課程大體分成線上學習階段和線下學習階段,線上課程的主要目標是幫助大家從編程語言開始,學習並掌握 Golang 和 Rust,逐步學習關鍵的理論知識。

TiKV 方向課程內容

TiKV 是 TiDB 的分散式存儲層,它本身也是一個高性能、可水平擴展、支持分散式事務的 Key-Value 資料庫,目前已經成為了 CNCF 的孵化項目。在課程內容的制定上,我們主要參考了 TiKV 現有的技術棧:

1. Rust 編程語言。TiKV 主要使用 Rust 開發,根據 GitHub 統計,99.5% 的代碼是 Rust。我們選擇 Rust 主要看中了它的內存安全和高性能。

2. Raft 一致性演算法。Raft 一致性演算法主打可理解性,業界也有成熟的實現,TiKV 使用 Raft 演算法同步節點之間的狀態。

3. Percolator 分散式事務演算法。分散式事務是 TiKV 很重要的功能,TiDB 的事務也是基於這個演算法改進的。

語言真的是門檻嗎?

坊間傳聞 Rust 學習曲線非常陡峭,「rust steep learning curve」 關鍵詞在 Google 上有超過 70 萬條搜索結果。誠然,Rust 有些概念確實比較隱晦,比如 static lifetime,Sync 和 Send,但它們也僅僅知識隱晦罷了,理解起來並不困難,結合我們的個人經驗來看,在實際編寫 Rust 代碼過程中也很少遇到不明所以的編譯問題,Rust 編譯器對於大部分的錯誤都提供了詳細的解釋,我們只要按照編譯器的指導修改代碼即可。所以「Rust 學習曲線陡峭」或許是我們的刻板印象導致的。

紙上得來終覺淺,我們一致認為學習一門語言的最佳方法就是「動手去寫」。為了讓大家改變對 Rust 的印象,也為了讓新手能有一個平緩的開始,Brian(TiKV 成員,Rust 語言主要開發者)編寫了一套手把手的 Rust 教程——Practical Networked Applications in Rust,這個教程的目標是帶領大家循序漸進地開發一個 KV 存儲服務。

  • Tools:Rust 提供了完整週邊開發工具,比如包管理工具 - Cargo,代碼格式化工具 - rustfmt,代碼 linter - clippy,它們將給我們的開發帶來極大幫助。
  • I/O:在這個章節我們將學習 Rust 中的 I/O 操作,錯誤處理,比較並使用不同的 collection 類型。除此之外,還將使用 failure 和 serde 這兩個庫來構建強健的持久化 KV 存儲。
  • Networking:Rust 標準庫提供了完整的網路介面,我們將使用標準庫實現 client-server 的持久化 KV 服務,期間將學習 Rust 強大的 trait 系統,logging 和 benchmarking。
  • Concurrency:相信寫過並發編程的同學一定也寫過數據競爭 ??,在 Rust 中這將不復存在。這個章節我們將深入介紹 Sync 和 Send,體驗 Rust 的「Fearless Concurrency」。

教程的內容足夠深入,相信大家在完成後能無障礙地使用 Rust 進行日常開發。語言將不再是門檻問題。

PS:目前課程還在開發中,之後將添加非同步章節,教大家使用 Future 進行非同步編程。

帶你突破兩個重要的分散式演算法

大家在閱讀 TiKV 源碼時,如果不瞭解 Raft 和 Percolator 演算法,就很容易迷失方向,不知如何下手。就算了解這兩個演算法,實操過程中也有可能出現「知道大體做什麼,卻不明白為什麼要這麼做」的情況。因此在 Rust 語言課程完成之後,我們將繼續帶大家學習這兩個重要的分散式演算法。

關於 Raft,我們直接採用 MIT 6.824 課程,並將 Golang 的教材移植到了 Rust。6.824 提供豐富的測試,從 leader 選舉一路測到線性一致性。在移植教程的時候,我們想儘可能地使用最簡單的代碼來實現,方便大家理解課程內容。但是移植過程並非一帆風順,其中最大困難是 goroutine 的代碼。在 Golang 可以隨時開啟 goroutine 執行非同步的代碼,但是 Rust 沒有類似的功能,考慮再三,我們最後決定使用 Future 來寫這類代碼。

在移植完代碼後,我們還驗證了代碼的正確性,驗證 Raft 的測試框架教程的思路也很簡單,用一個正確實現了 Raft 的庫來跑一遍教程中的考覈測試。我們選擇了 github.com/pingcap/raft 這個項目,測試一遍後修復了幾個 BUG。不過事實證明只測試一遍是不夠的,課程發布後社區小夥伴在學習過程中,又陸陸續續發現並解決了幾個 BUG,在這裡特別感謝 @wjhuang 和 @NingLin-P 兩位同學的貢獻。

至於 Percolator,由於沒有現成的教學課程,我們決定從零開始設計。好在有一部分可以直接復用 6.824 代碼,比如網路框架,它是比較通用的網路測試框架,可以模擬多種常見的網路錯誤,比如丟包、亂序等。Percolator 的測試也比較豐富,從 TSO 到 lost update 再到 read/write skew 最後到網路錯誤,都有覆蓋。

學完這兩個演算法後,相信大家能達到「知其然,又知其所以然」的程度,再看 TiKV 代碼的時候不會一頭霧水。之後我們還將補充更多內容,比如 multi-raft、集羣調度等,終極目標是讓大家可以實現一個簡易版 TiKV。

另外值得一提的是,在線下課程中,我們將著重介紹 TiDB/TiKV 架構,帶領大家瞭解實現原理與細節,還有專門的 Mentor 指導大家深度參與 TiDB/TiKV 開發。更多的細節已在 這篇文章 中披露,在這就不贅述了。

FAQ

PingCAP Talent Plan 已經成功舉辦了兩期,期間我們收集了學員的一些問題,在這裡挑幾個比較有意思的和大家分享一下。

Q1:github.com/pingcap/tale 是如何組織內容的?

A1:talent-plan repo 裡面有 3 個文件夾,/tidb 存放著 TiDB 相關實驗,/rust 存放 Rust 課程,/dss 存放 Raft 和 Percolator。

Q2:dss 是什麼意思?

A2:好問題,可能我們內部人員都不一定知道。dss 其實是 Distributed Storage System 的縮寫。??

Q3:Raft 測試為什麼會卡住?

A3:大部分情況是在 RPC 的 handler 裡面寫了會阻塞的代碼,受限於 Rust 的 Future 機制,我們不能 100% 地模擬 goroutine,後臺執行 Future 的線程數量是有限的,如果 RPC 會阻塞,並發上來後就會卡住。

Q4:dss 為什麼會 #[allow(dead_code,unused)]

A4:這是因為我們留了一些公開 API 交由學員實現時使用,測試本身不會直接用到,這就導致了 dead code 的誤報。這些 allow 我們是要求學員在提交的作業的時候去掉的。有不少學員沒有注意這點而被扣分了。

Q5:dss 需不需要寫注釋?

A5:需要!不寫會扣分。我們堅信注釋是代碼的一部分。

關於 PingCAP Talent Plan 的 TiKV 方向的課程暫時就介紹到這裡,最後向 MIT 6.824 的工作人員致謝,感謝他們開源了優秀的 Raft 教材。

PingCAP Talent Plan 第三期線下課程 已於昨日開啟,我們來到了華中科技大學開始為期一週的集中授課,之後學員們將前往 PingCAP 北京總部在 Mentor 的帶領下繼續學習 TiDB/TiKV 相關知識並上手實操,在這裡預祝大家順利結業!

推薦閱讀:

相關文章