谢邀!
我是大三寒假做的,做的是talent plan 2.0的路径2:tinykv,最终打分是87.3分。
由于我对于分布式系统这一块非常感兴趣,并且也听说过大名鼎鼎的talent plan课程,所以当时在年级群看到了万老师实验室的招新信息之后毫不犹豫的就报名了。事实证明我的决定非常正确,参加这次实习不仅学习到了丰富的知识,深入的参与到具有挑战性的工程项目而且还认识了许多大佬。当然,你还将获得pingcap的一份证书,以及周边(一个充电宝以及两件T恤,纯棉的)。
下面简单介绍一下tinykv项目:
一共有四个project:
- project1是构建一个单机kv server
- project2是基于raft算法实现分布式键值数据库服务端
- project3是在project2的基础上支持多个raft集群
- project4是在project3的基础上支持分布式事务
该项目是由go语言实现的,这门语言上手非常简单,而且用熟了之后就会爱不释手的。
项目的的代码编写十分规范,并且代码写的十分优雅,读它的源码也可以学到不少东西。
测试用例蛮完备的,能够捕捉到你的代码的绝大部分bug。
指导文档不是很详细,当看了文档不知道要干什么的时候,建议多读一读相关的源代码,然后再看文档就能理解它的意思了。
经验分享
我发现实验的解题思路楼上的几个大佬已经说的很详细且牛逼了,那本菜鸡就来谈一谈调试吧QwQ
调试:建议使用打日志的方法
一种可以自己控制开关的DPrintf的实现,调试的时候会非常有用
const Debug = 0
func DPrintf(format string, a ...interface{}) (n int, err error) {
if Debug > 0 {
log.Printf(format, a...)
}
return
}
建议将输出重定向到一个文件当中进行分析:
- 2B,2C,3B里面的generic test随机测试会输出大量信息,所以在terminal里面只能看到最后一部分日志
- 将文件的后缀命名为.log的话,编辑器的插件还会高亮你的日志,阅读起来更加清晰
- 在文件中分析日志可以很好的利用编辑器的查询功能
- 能力强的同学甚至可以根据你打日志的格式写出一个程序帮你分析日志
可以利用打日志的方法二分定位一些错误。
如何打日志的建议:
举一个例子来进行说明,比如在实现raft算法的时候,我们可以在收发消息的时候打印出接受者id,发送方id,当前任期,以及当前是选举请求还是心跳包,是接受了还是拒绝了等等信息,这样我们通过查看日志可以完整的复现出整个流程,调试会变得轻松许多。

不要等到所有的代码写完了再进行测试,而是写一部分测试一部分。我在project1以及project2A里面完全是面向测试编程的,就是根据这个测试点测试的功能实现对应的几个函数对应功能,直到通过该测试点,然后下一个测试点继续这个过程。不过完全面向测试编程付出的代价也非常惨痛,在project2B里面运行测试会报出一个panic的错误,后来阅读了好几天的源代码,在纸上画出框架代码的运行流程,在底层代码里面插入许多打印函数才找到并修复了2A里面的一些bug。
2B,2C以及3B的GenericTest实在是太复杂了,很难读懂,并且最后我也用实践证明了读懂了也没有什么用,所以这三个Part建议按照需要实现的功能进行编程,然后分析运行测试之后的日志找BUG。由于这一部分的测试很吃内存,所以最好利用Goland的单点测试功能一个一个测试点的测试。另外由于这一部分是随机测试,运行成功了不代表程序没有bug,并且有的bug可能要跑好几次才会触发,我的做法是写了一个简陋的脚本跑每一个Part对应的最后一个测试点50次,并且保存对应的输出日志。这一部分可以说是整个实验里面最难的了,也是我花的时间最多的了。
由于已经过去了几个月了,目前本菜鸡能回忆起来的只有这么多了QwQ。
最后谈一谈项目之外的经验总结吧:
当你感到这个项目太困难,坚持不下去想放弃的时候,请再坚持三天。这一条“三天定律”在我的身上已经应验了无数次了
- 第一天的时候,内心OS:这什么东西啊,哥根本看不懂,不学了;
- 第二天:咦,这个函数原来是这个用处啊,妙啊;
- 第三天:基本熟悉了代码的框架,搞懂了函数间调用关系以及执行流程,知道想要添加什么功能的时候需要在哪里加代码,感觉也没有那么难了。
一定要养成做笔记的习惯,不然当你做完一个项目再过几月回来的时候你会发现,你不认识它,它也不认识你。会觉得自己之间做项目的时间白花了,现在啥也不记得,满满的懊悔感。而且就tinykv项目来说,文档是有20分的,你做的笔记也可以作为文档的一部分交上去,说不定还可以多拿几分呢!
对于这种大型的项目,要有一个宏观上的认识,不能只局限于一个测试点,我印象非常深刻的就是第一次去开会分享的时候,校交班的一个大佬在present的时候是先把四个project全部看了一遍,从宏观上讲述tinykv的架构,真的佩服!
2B是这个实验的分水岭,技巧无他,唯砸时间尔,多花点时间看代码,总能够搞懂的!
最后,来一波致谢!
非常感谢万老师能够同意我来到实验室实习, 能够接触到tinykv这么优秀的开源项目, 非常感谢pingCAP团队开源这么好的项目以及社区的源码解析的系列博客, 让我学到了许多知识, 非常感谢学⻓以及同学们对我的帮助, 解决了我许多的疑问. 看了一下git log, 从提交project1到提交project4C, 这之间一共历时25天. 在这个过程中更深一步的了解了Raft算法, 了解了facebook公司开源的存储引擎rocksDB, 了解了tinykv的系统的架构, 了解了调度器的一些工作原理, 了解了分布式事务的二阶段提交, 以及MVCC等技术.记得在做2B的时候, 有几天非常自闭, 也想过放弃, 但是非常感谢当时的自己坚持下来了! 这一次的实习收获非常多!
(逃