我和 TiDB 的故事 | TiDB 仓库 commit TOP 1,PR 数超过 1000 的阿毛哥

大家好,我是毛康力,来自 PinCAP 的研发工程师。我的 github ID 是 tiancaiamao,目前在 TiDB 仓库的 commit 数排名在 top1。在 TiDB 相关的各个项目总计 PR 贡献累计超过 1000 了。

相遇

我在 TiDB 仓库的第一个 pr 应该是 2016 年的 6 月 21 号。 因为工作原因,我在 2016 年 4 月份加入了 PingCAP,先是在 tikv 那边干了一阵子,但是写 Rust 不太习惯,然后就转到 TiDB 这边写 Go 了。对我自己来说,还是 Go 语言写起来比较舒适。再接下来就是持续的给 TiDB 提 PR 了,这一干就是持续好多年。

选择加入 PingCAP

我接触 Go 语言比较早,而早期使用 Go 语言的公司并不算多,PingCAP 是其中之一。然后也有关注到 TiDB 这样的 Go 语言实现的"明星"项目。

一个契机是,早期的活跃的 Go 语言用户同样也不算多,我自己有写博客的习惯,当时主要是一些关于 Go 方面的内容,东旭正好通过博客关注到我,于是就约着聊聊。就这样擦出了火花,于是我就来贵司了。

最初我是在广州的,而 PingCAP 在北京,所以对于换城市会有一定的顾虑。而正好 PingCAP 的文化是支持 remote 的,这点就非常有吸引力了。 站在现在的角度看,虽然作为一个老司机,我已经 remote 好多年了,习以为常。但是当时还是挺震憾的,文化上非常的开放和自由,宽松的工作氛围,追求结果而关注过程。

现在 PingCAP 在全国几个大城市有了 office,海外也加入了不少同事。一个 team 可能遍布在好几个地方,并不能大家都在一个办公室,有事吼一嗓子,或者直接去工位找某某某。其实大家也都习惯了"线上"协作的模式,提 PR,review PR,线上会议等等,这都是跟开源的协作模式很契合的。

像我所在的团队就有分布在国内几个城市,以及在欧洲和北美。导致一个问题是,跨越了多个时区,开会聚集不到所有人。处理方式就是,比如今天由国内跟欧洲开会,明天再国内同步到北美那边。由于分布在不同的城市,一个 team 的同事可能都没线下见过,如果 team building 聚一聚时,会发现大家可能相互 review 过 PR 和线上讨论过问题,但是却又还"不认识"对方,于是我们戏称为 “网友见面”。

谈一谈 TiDB 贡献者们

TiDB 贡献者们来自各行各业,也都有着不一样的身份,但是他们都有一个共同的身份,就是 TiDB contributor 。

比如说有学生。尤其是有些国内排名靠前的大学,学生都很猛的,还没毕业就早早关注到一些开源项目,并参与贡献一些 PR。像我自己毕业时的那个年代,对于开源项目这些东西都还没有什么概念。现在实在是太"卷"了,没有一些开源项目的贡献,大公司实习之类的经历,可能简历关都过不了。 我时常调侃,还好加入得早,要不然如果是换成他们先进来,再来面试我,我就被他们拍死在沙滩上了。

关于学生这块,我们有时候也组织一些面向高校的活动。比如说 TiDB-challenge-program 的活动,也是会吸引一些高校学生参加。我们会发布一些特定的小项目,我自己作为 mentor 带过一些,感觉真的是很优秀的同学,对比一下由开源这一块吸引到的贡献者,比简历投递过来的质量往往要高不少。 所以这也是招聘的一个很好的来源。早些年,我们会给 TiDB 贡献过代码的外部贡献者发一些小礼物,比如说有送件文化杉啥的。如果发现了穿着我们送的文化衫的"野生"贡献者,要赶紧拉住要简历。因为公司内推是有奖励的,所以这种人被我们称之为 “行走的 iPhone”。

扯远了…说回 TiDB 贡献者的背景,除了学生,也有来自学术界的。印象很深的一个是 Samuel,是一个国外的大学教授。开发了一个 Squirrel 的测试工具,发了篇论文,里面用到了一些模糊测试的方法,在 TiDB 上面验证过,帮我们挖了不少 bug 出来。再后来,他有个博士生,github ID 是 bajinsheng。在 Samuel 的基础上继续深入,做了个叫 sqlance 的工具,也给我们找了好多 bug。工具太厉害了,效率很高,一个人的战斗力超过一个团队。那阵子他比我们自己的 QA 整个团队加起来找得 bug 都还要多。github issue 里面搜 label:fuzz/sqlancer 可以看到这些记录。贡献不一定是单指代码,像这种帮忙找 bug 发现问题,也是一种形式的贡献。

类似的还有 TAOBench 作者,也是有一篇 paper 的,他们构建一个性能测试的工具,里面的实验验证有用到 TiDB 和其它几款数据库产品的对比。这些研究工作对我们的产品性能提升会有帮助,后来我们内部也把这些成果纳入了我们 benchmark 测试的 workload 里面,日常跑着。 严格来说 TAOBench 作者是来自 facebook 的,应该算是工业界了,但因为论文的关系,我还是归到学术界这边。

至于工业界,来自于这块的贡献就更大了。我们的不少的 committer 都是来自外部公司的。说明一下,给 TiDB 提过 PR 这种我们叫 contributor,当 contributor 持续提一些 PR,对某个模块具备足够的了解之后,我们会提名为 reviewer。足够活跃并且对整个 TiDB 做出了比较大的贡献之后,我们才会提名 committer。 像 SpeedCloud 的李雨来就是为我们贡献了最初版本的 plan cache 的实现,于是成为了 commiter 的。还有晓光老师也是我们的 committer,之前是在知乎。在 PingCAP 内部,其实也是同样的流程,要一步一步提 PR 才从 contributor 到 committer 或者 maintainer,这点对公司员工跟外部贡献者并没有区别。

有很多公司在用 TiDB,会给 TiDB 发现一些 bug,有些是提 issue,有些就直接 PR 甩上来的。尤其是互联网公司,都是很有这种直接"撸起袖子就干"的风格的。于是这些用户也就成了我们的贡献者。

从地域角度来说,贡献者来自全世界的都有,虽然国内的更多一些。记得一个很好玩的事情是,以前有个俄罗斯的小哥,给我们提过 PR。我说过,我们当时都会给贡献者送些小礼物啥的,然后我们同事就联系到人家,说给寄点东西过去。对方持着很怀疑的态度,在担心我们是骗子或者是在套他的个人信息啥的。 最后我们真的把礼物寄到俄罗斯了,小哥表示非常惊奇,也很高兴能收到礼物。虽然不是什么值钱的东西,这算是一种公司文化吧,我们一直是非常重视开发者的。

TiDB 代码贡献之路

我们的开发活动都是在 github 上面,公开透明。整体上看,日常的 workflow 都是围绕着 issue 和 PR 展开的。如果是简单的场景,直接提 PR(pull request) 就行了。PR 一般是需要得到两个 reviewer 以上的角色的 approve 之后,就可以将代码合入到 master 主干分支。

如果是对于复杂一些的场景,比较说开发一个新的 feature,流程上需要有文档,设计和讨论。内容也会以 issue 之类的形式放在 github 上面。比如说参见临时表的开发过程。

我想说的是,这一切都是对外开放的,真正的开源协作的模式。

用户需求

github 上面的 issue 更加面向研发一点。如果是对于普通的用户,可以到 AskTUG 上面提问,这是一个属于用户群组的社区。

我们会收集用户的反馈,需求一般是几类来源,一类是这种社区的呼声比较高的问题。再一类是从企业版客户那边,在使用过程中得到的反馈。还有一些比如某些重要的 PoC,客户看中某一块的能力,我们还没支持。

PM 会整理这些需求,然后按优先级排期,研发这边会不断地改进产品。产品会不停地迭代,每个小版本我们都会有一些 feature 或者改进带出去,小步快跑的模式发布。

隔一定的时间,我们会发一个大版本,大版本往往都是带了比较重大的 feature 或者改动。现在我们会有 LTS(long term support) 的版本,追求稳定可以随 LTS 版本升级,而想快速尝鲜或者是等待某个新 feature 的用户可以用非 LTS 的版本。 这样同时保证了稳定和快速迭代,满足不同场景的用户需求。

收获

我自己算是跟随 TiDB 一起在成长吧。早期的 TiDB 代码规模比较小,团队也没有划分得很细,每个人都会涉及许多个模块,这样基本上可以熟习整体架构和所有的模块。你可以在 parser,事务,分区表,DDL,优化器,执行器等等几乎所有角落看到我的代码提交记录(哈哈)。 现在的团队划分更细了,专注各自的模块,可能就没有我当时那么好的学习的机会了。

除了涉及到的技术层面,我觉得一个很重要的收获是作为一个工程师的综合能力。这个听起来就比较虚了,只有经历过,才知道怎么样维护这么大一个开源项目。怎么样保证产品质量,并且可控地迭代。如何与他人协作去推进一个事情。 大公司里面可能会有一些测试和 review 的规范化的流程,但是规范程度很难达到这种大型开源项目的标准。通过每一个 PR 提交细节,就可以看到这些工作的严谨。开源的项目可以知道谁,在某一次提交做了什么,被全世界所有的眼睛盯着,所有不规范的行为,都是被钉在耻辱柱上的。

开源文化

我觉得开源一定是要形成一个社区。把代码放出来,然后不管了,那样不叫开源。但有些公司就是喜欢这么玩,内部的产品竞争中败下阵来,于是直接把源代码往 github 一扔,就号称开源了。完全看不到后续 PR 和更新,也没有人在回答问题和解决 issue。

开源的概念火了起来,有些基础软件赛道的创业公司,PE 估值很高。就会有些人跟着蹭一波热度,这都是把开源当噱头,这都是假开源。 更过火的甚至出现了某公司,做活动推广刷星,只要给他们 github 项目仓库点赞就送礼物。这种形式做出来的 star,对产品本身是毫无意义的。当然,如果投资人傻的话,也许给投资人看可以糊弄下: “你看,我们涨星趋势比当初的 TiDB 还要猛”。把开源当 KPI 来做,那肯定是做不成的。

不对的人对开源的文化有不同的理解。比如以 GPL 协议作为切入点来看,这是一个"病毒"传播协议,使用它的代码会被感染,也要求按 GPL 协议开源。但它确实是反技术垄断,打破专利壁垒的有效武器。对比一下,某头号数据库厂商,一个据说律师比程序多的公司,具体做了哪些贡献是推动技术进步,时代发展并且让所有人受益的事呢?源码在手,就意味着自由,而不是封闭,free! free 是自由,而不是免费的意思。也有像 MIT 这类的协议,放弃了对软件的诸多权利,这跟 GPL 不太一样,但在 free 这点上都是共通的。

不同的时期,推动开源运动的主力也在变化。早期更多一些个人英雄主义的开源项目。现在更多的是机构和大公司在主导着开源项目。这里面其实也有些利益的因素,是否拥抱开源,跟公司的认知有很大关联。

如果一个公司觉得,代码是核心资产,开源是劣势,会导致竞争对手抄袭自己的代码,从而后来居上,那么他就应该选择闭源。 如果一个公司觉得,开发者才是核心资产,那他应该打造一个开放的社区,吸引到更多的贡献者,让这个社区变得更活跃,更强大,从而产品也能更完善。因为抄代码是好抄,但是构建一个活跃的社区却是有很高的壁垒的。

当然,也会有一些分裂社区的行为,比如说,如果一个公司觉得既然代码都开放了,那么何不 fork 过来,再自己改一套,然后闭源卖企业版或者啥的。 这么做完全可以,只要没违反相应的开源协议。事情背后的本质,变成了这家公司,对抗整个社区的游戏。如果它的投入够大,它的迭代速度比原始项目更快,产品做得更好,用户就会吸引到它的阵营来。只是这个过程代价很大,需要这家公司的投入,大于整个社区的其它公司和个人贡献者的投入总和。

为了防止分裂,最好的做法就是让社区更活跃,参与者更多,由多家公司来一起推动。使得分裂社区的成本由单个公司无力承担。最后要么选择加入,要么对抗并失败。开源的规则就是这样玩的。有一个典型的例子就是 chromium,软件的复杂性使得没有哪一家公司能 fork 一个出去,然后自己另起炉灶的。一旦形成了事实标准之后,项目牵头的公司成为最大的受益者,属于是阳谋了。再比如 android 的例子,只有构建好生态,才能有无数的贡献者参与进来,写驱动,写 app,写各种东西,然后整体生态越来越强大。

从这个角度,我觉得开源的文化,就是反映人背后的认知。最终符合生产力发展规律的事物,会取得最后的胜利。相比于闭源/假开源,一开始就坚定选择开源的人,格局简直是在大气层了。

建议

如果说给最其他打算成为 TiDB 贡献者的人一些建议?硬核的方式,当然是 read the f*cking source code 啦。读代码的过程中,发现有什么问题可以在 github 提出 issue 讨论,或者代码方面有改进的点可以提 PR。读代码适合有一定基础,并且喜欢这种风格的程序员。

更平滑一些的方式,可以先从一些文档开始学习,了解一下系统的整体架构,官网的博客就是一个比较好的学习资源。有大概的熟习之后,可以从一些小的 PR 开始做起,在 TiDB 的 issue 里面搜索带 help wanted 标签的 issue,一般是比较适合于新人上手的。 至于怎么提 PR,在项目的 README 里面有一块 How to contribute

关键是参与进来,接受反馈并不断学习,相信 TiDB 一定会让贡献者有很好的收获的。

3 个赞

前排膜拜大佬~

牛的,咱写代码是不行的,读都只能勉强读一读,也膜拜下吧。。

前排膜拜!

仰望大佬! :eyes:

膜拜大佬

膜拜大佬,对于运维的DBA有什么建议吗?

膜拜大佬!

日常膜拜大佬!

阿毛哥说得好实在

1 个赞

膜拜大佬,现在tidb数据库真的挺好用的,感谢大佬

敬仰!