我们是如何设计 Rust & 分布式存储教程的? | Talent Plan 背后的故事

作者:沈泰宁 唐刘

许多人眼中的 PingCAP Talent Plan 可能就是 github.com/pingcap/talent-plan 这个项目,但从内容角度来说并不完整,这个 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-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 开发。更多的细节已在 这篇文章 中披露,在这就不赘述了。

FAQ

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 相关知识并上手实操,在这里预祝大家顺利结业!

你可能感兴趣的:(数据库,rust,raft)