做者:沈泰寧 唐劉git
許多人眼中的 PingCAP Talent Plan 可能就是 github.com/pingcap/talent-plan 這個項目,但從內容角度來講並不完整,這個 Repo 只是線上課程的內容,咱們還有與其配套的線下課程。 本文將從課程設計的角度和你們聊一聊 PingCAP Talent Plan(TiKV 方向)課程,包括課程設計的邏輯、課程設計中遇到的困難,以及你們在學習過程當中常見的問題和解答等。github
TiDB 是一個新型的開源分佈式關係型數據庫,目標是但願在大數據和雲時代的新的業務需求下,幫助你們更好地解決數據大規模存儲和實時計算的問題。咱們據說不少同窗跟咱們反映他們很想參與到這些項目中去,但遇到了一些問題:算法
編程語言是參與項目的敲門磚。Golang 和 Rust 都比較新,須要必定的學習,是最直接的高門檻。數據庫
理論知識是深度參與的基礎。從理論到實踐有一道鴻溝,並非這麼容易跨越。編程
爲了解決上述問題,咱們啓動了 PingCAP Talent Plan。目前課程主要分爲兩個方向,面向 SQL 優化器、分佈式計算的 TiDB 方向,和麪向大規模、一致性的分佈式存儲的 TiKV 方向。課程大致分紅線上學習階段和線下學習階段,線上課程的主要目標是幫助你們從編程語言開始,學習並掌握 Golang 和 Rust,逐步學習關鍵的理論知識。安全
TiKV 是 TiDB 的分佈式存儲層,它自己也是一個高性能、可水平擴展、支持分佈式事務的 Key-Value 數據庫,目前已經成爲了 CNCF 的孵化項目。在課程內容的制定上,咱們主要參考了 TiKV 現有的技術棧:網絡
Rust 編程語言。TiKV 主要使用 Rust 開發,根據 GitHub 統計,99.5% 的代碼是 Rust。咱們選擇 Rust 主要看中了它的內存安全和高性能。架構
Raft 一致性算法。Raft 一致性算法主打可理解性,業界也有成熟的實現,TiKV 使用 Raft 算法同步節點之間的狀態。併發
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-rs 這個項目,測試一遍後修復了幾個 BUG。不過事實證實只測試一遍是不夠的,課程發佈後社區小夥伴在學習過程當中,又陸陸續續發現並解決了幾個 BUG,在這裏特別感謝 @wjhuang 和 @NingLin-P 兩位同窗的貢獻。
至於 Percolator,因爲沒有現成的教學課程,咱們決定從零開始設計。好在有一部分能夠直接複用 6.824 代碼,好比網絡框架,它是比較通用的網絡測試框架,能夠模擬多種常見的網絡錯誤,好比丟包、亂序等。Percolator 的測試也比較豐富,從 TSO 到 lost update 再到 read/write skew 最後到網絡錯誤,都有覆蓋。
學完這兩個算法後,相信你們能達到「知其然,又知其因此然」的程度,再看 TiKV 代碼的時候不會一頭霧水。以後咱們還將補充更多內容,好比 multi-raft、集羣調度等,終極目標是讓你們能夠實現一個簡易版 TiKV。
**另外值得一提的是,在線下課程中,咱們將着重介紹 TiDB/TiKV 架構,帶領你們瞭解實現原理與細節,還有專門的 Mentor 指導你們深度參與 TiDB/TiKV 開發。**更多的細節已在 這篇文章 中披露,在這就不贅述了。
PingCAP Talent Plan 已經成功舉辦了兩期,期間咱們收集了學員的一些問題,在這裏挑幾個比較有意思的和你們分享一下。
Q1:github.com/pingcap/talent-plan 是如何組織內容的?
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 相關知識並上手實操,在這裏預祝你們順利結業!