2019 年,终于终于,正式从上海交通大学研究生毕业,踏上了工作岗位。这其中的身份转换,是今年的主题。
一月上旬,是我毕业答辩的日子。去年的年终总结,在 11 月份就写好了,就是因为 12 月份预感到要进入毕业论文的最后冲刺中。答辩的过程有惊无险,顺利通过。回顾一下研究生度过的两年半,简直就是跟论文搏斗的血泪史。好在最后还是顺利毕业了,感谢实验室不杀之恩。这个月在答辩结束后,基本没怎么写代码,很多时间是在 review 一些 Kubeflow 上游的代码,或者自己写一些自己感兴趣的代码等等。
二月份,新年来了。这个月没有什么别的事情,就是看看书,打打游戏,在家里度过了一个平和的新年。在 16 号的时候,我和小徐,以及两个大学同学一起去了北海道,小徐的博客上有一篇游记专门介绍了我们的行程。我们一起去了小樽,札幌等地方。札幌的动物园给我留下了最深刻的印象,如果要让我推荐一个必去的景点,一定是札幌动物园。而且一定要去看企鹅散步表演,小企鹅实在是太萌了。
三月份,完成了毕业典礼,租好了房子,正式开始了工作生活。入职没几天正好赶上发布版本,协调后去与同事(看之前的总结发现每次把共事的同事 @ 出来后没多久就会出现同事离职的惨剧,所以这里就不具名了)一起合作开发模型服务功能。因为之前一直在做开源相关的事情,对公司的产品架构不太熟悉,因此初次参与开发,花费了一段相对较长的时间理解需求和现行架构。同事带领着我一起逐步走向了正轨。
四月份,基本每天都在火热的开发过程中。因为我自身对代码和架构有一些完美主义,以及对单元测试有莫名的执念,再加上纸面上的 Deadline 一直追赶着,这段时间基本每天都会有一个 PR 被合并,时常出现一天编码 12 小时,吃完外卖立刻投身工作的情况。但后来仍然没有避免延误的发生 XD
由于工作的办公室距离住的地方,有大约单程 1 个多小时的通勤时间,因此每天有大约 2 个多小时的空闲时间。趁着这段时间,在四月份开始,我试着在路上阅读一些论文,效果还不错,在四月份一共读了 10 篇跟模型服务相关的论文并写了阅读笔记。唯一的问题就是办公室的打印机打印双栏论文质量不太高,每次路上看完都会感觉眼睛非常疲劳。
五月份,虽然产品还没发布,产品开发的过程告一段落,经过跟同事和 Lead 的沟通后,开始着手参与 katib 的开发。旧版本的 katib 对数据库有非常强的依赖,因此很难说它是一个 Kubernetes Native 的系统。而且数据库主要的角色就是从 Kubernetes 的 etcd 中备份数据出来,其实是非常冗余的,而且会影响可用性,如果备份失败,甚至会影响正常流程。在这样的背景下,我们与 IBM,Google 和 Cisco 的同事合作,希望把它改造地 Cloud Native 一点。在这个月中,一共提了 30 个 PR,review 了 110 多个 PR。这些修改都是对之前版本的修修补补,因为本身还在产品流程中,没有太多的时间对整体的架构进行重构。
六月份,再次回到了产品的功能开发中。我和肉肉在月初一起去了一次苏州博物馆,在博物馆附近吃了一家人气爆炸的三虾面店,味道还真挺不错的。这个月的工作主题是和 istio 搏斗。我自己在之前对 istio 的了解几乎一片空白,在这个月中恶补了一下这方面的知识,坑是真的蛮多的(除了这些之外,这个月去 KubeCon 跟上游一起维护 katib 的同事们见了面,一起吃了一顿饭。作为东道主,还不是我付的钱,惭愧。
七八月份,相对开发任务没有那么重了,终于开始着手设计 katib 新版本的特性和架构。这个时候,同一个实验室的吴学弟也来我们公司开始了暑期实习。学弟的开发机是 MacBook,而我很久很久没有接触过 macOS 的操作系统了,所以遇到了好多环境问题。在这两个月我们一起设计了 katib 的 Suggestion CRD,并且高频率地跟上游一起讨论,最终达成了比较好的结果。这段时间我的英语(尤其是印度风格的英语)听力水平突飞猛进,算是意外之喜 :-)
九月份,基于之前对于 katib 的新版本设计,开始了实现。这个月算是一段密集开发的时间,一个月的时间完成了新版本的大部分功能。
十月份,一方面由于 Kubeflow 上游准备发布新的版本,因此继续 katib 的 Bug 修复和特性维护工作。另一方面,开始着手 AutoML 在产品上的落地,进行产品的一些设计工作。在每个周末的闲暇之余,参与了 Ray 社区关于 Kubernetes 集成的一些方案探索。
十一月份,彻底进入了产品的开发阶段,又是一段密集开发。跟上游类似,由于产品比较早期,基本每次的新版本开发都是一次重写的过程。这个月,我和小徐各自买了一个 10 寸的电子书,用来在来回接近 2 个半小时的通勤时间里看书学习一下。我非常喜欢这个产品,导致小徐经常抱怨我到哪里都拿着它看书,以至于没有与她好好相处的时间了。这个月,我们公司开源了一个我认为比较有前途的项目:caicloud/ftlib,这是一个用来实现 RingAllReduce 分布式训练的容错和动态扩缩算力的底层库。它底层依赖了一个 Gossip 协议,上层依赖了 NCCL,来做到容错。不过底层和上层的依赖都是可以扩展的,我们公司的同事正在和蚂蚁金服的同学一起开发中。
十二月份,毫无疑问,产品开发。期间 Ray 社区关于 Kubernetes 的讨论最终收敛了,社区决定接受来自蚂蚁金服的贡献,在周末或者晚上,也帮忙进行了一些 Code Review,主要结合我们内部采用开源 CRD 实现的过程中经常踩的坑,在 API 设计的层面留了一些评论。目前我还不确定蚂蚁是如何解决 Ray 集群在 Scale Down 的时候是如何保证尽可能下线没有 Actor 节点的机器的,不过在跟一位蚂蚁的前辈交流过程中,了解蚂蚁的这一套方案在内部已经有所采用,因此稳定性是经过一定程度的测试的,所以也没有再纠结。蚂蚁有贡献的热情,对于我们而言自然乐于摇旗呐喊,希望 Ray 能够被更多地采用。
这一年,由于工作后通勤时间大大增加,每天在路上的时间特别多,因此在这段难得空闲的时间里,我读了不少的论文和书籍。在十一月份,我又又又读了一次《计算机网络 自顶向下方法》。这本书在本科的时候读过一半,研究生的时候读过另外一半。但仍然觉得当时有很多内容没有理解太深,因此又读了一次,收获还是很多的。计算机领域的很多问题感觉都是相通的,虽然不是完全一样的领域,但是遇到的问题,解决问题的思路,都是类似,以及可借鉴的。这本书真的特别推荐,作为计算机网络的入门读物非常合适。
除此之外,有两本关于内核的书也非常值得推荐:《Linux Kernel Development》和《Understanding the Linux Kernel》。尤其是前面一本,它从一个内核开发者的角度,带读者了解了 Linux Kernel 中的一些设计和实现,但同样对 Kernel 的用户也很有帮助。其中对于进程调度,中断处理,并发控制等等各个方面写的都很好。读完之后能对 Kernel 有一个更加宏观的认识。
在语言学习方面,我目前并没有找到学习 Go 语言源码比较好的书籍。听闻《Go 源码剖析》不错,但读完觉得它贴了太多代码,不是个人喜欢的风格。
在设计模型方面,我也又又又读了一次《大话设计模式》,这本书读了大概有三遍了,奈何随着时间推移,有些不常用的设计模式基本很快就不记得了。这次捡起来只是日常性的回顾。这本书还是值得推荐的,行文非常轻松愉快,甚至可以当做轻松读物来看待。
在分布式领域,最近仍在读一本书,是杜军前辈的《云原生分布式存储基石-etcd 深入解析》。这本书的特点是铺垫的特别好,会先从分布式的一致性问题开始讲起,介绍拜占庭将军问题,RSM,FLP 不可能,CAP 理论等,再一步步引入到 Raft,etcd。所以就算没有分布式的知识背景,读起来也能有所启发。
今年认真读过的论文大概在 30 篇左右,其中跟模型服务有关的大约在 10 篇,跟 AutoML 相关的大约在 10 篇,剩下 10 篇跟集群调度,分布式等等其他领域有关。在模型服务领域,可以推荐一下一篇 17 年的论文:《TensorFlow-Serving: Flexible, High-Performance ML Serving》,是谷歌 TFServing 的论文。这篇工程的味道比较重,也比较经典。在 AutoML 领域,综述论文越来越多了,如果是初步了解的话,推荐《Automated Machine Learning: State-of-The-Art and Open Challenges》这篇,介绍的比较全面。集群调度方面,我个人最喜欢的一篇文章是 《Tiresias: A GPU Cluster Manager for Distributed Deep Learning》。这篇文章还没来得及写笔记,但它的观察很到位,算法相对简单,有更大的落地可能。
到目前为止,我已经工作了大半年了。在这段时间里,确实跟在学校里有不同的感受。工业界在我看来,对架构设计方面,要求更高一些。在一次典型的发布中,编码应该是一个没有风险,只需要工作量的阶段。所有的风险应该在设计时充分考虑,分析清楚。这对工程师的架构设计能力有着更高的要求。在学校的时候,我通常喜欢先写一个原型出来,然后在修改的过程中不断重构。这就像是动态语言一样,边解释边执行。而在公司里,这一流程更像是静态语言,需要先针对需求进行详细的方案设计与评审,在评审(也就是编译)通过后,才能真正去展开编码。其实这样更符合软件工程将风险提前的思想,可以降低在编码阶段遇到运行时错误,需要重新设计的风险,保证按时发布。这是一个很大的不同。
其次,工业界对完美主义不特别友好。对于技术债务的处理上,如果在学校里,我可以停下来花上几个月的时间专门去做代码重构的工作。而在公司里,更多时候是在给运行的汽车更换轮子。换一个全新的轮子,让车子能够跑的更久,并不是最高优先级的事情。给车子加更多特性,让车子跑的更快,是更重要的。这就会导致你的车子看起来外表破破烂烂,各个零件似乎随便掉一个就散架,但它就是能跑的快,又是一个 trade-off。这跟前面的一个特点相呼应,有一种奇异的感觉。一方面,在对设计评审的时候会相对严格,但是另一方面,由于时间等各种各样的关系,对于实现时的评审又相对放松。
今年基本身边所有的同学都走上了工作岗位,我也越来越忙碌。似乎跟之前的同学们见面的机会越来越少,希望明年能够有更多时间让自己不这么自闭。除此之外,明年希望能够继续在分布式和操作系统方面加强一下认识。工业界系统的学习方面,暂定的子方向是消息系统和机器学习框架。消息系统一直是我个人比较感兴趣的一个方向,但之前在学校里一直没有机会接触和学习,现在工作恢复了学习自由(空闲时间学习内容的自由),终于可以接触一下了,之前一直听说 nsq 的架构和实现都非常优雅,借此机会希望了解一下。而机器学习框架,是与工作息息相关的,值得多花一些时间来学习。之前粗略的读过 TF 的代码,明年想多关注一下 pytorch。
学术界的论文方面,一方面想保持对集群调度的关注,一方面想加强一下对一致性的了解。趁着难得的对 Paxos 的兴趣,想在明年把 Paxos 本身以及各类流行的变种认真学习一下。
Flag 就先立这么多,预祝大家新年快乐 :-)
往年总结
License
- This article is licensed under CC BY-NC-SA 3.0.
- Please contact me for commercial use.