2022 年终总结:记清华硕士的秋招之年

本文最后更新于:几秒前

前言

忙忙碌碌又是一年,终于到了 2022 年底。去年第一次写年终总结受到了不少的关注,我在这一年里也时常会重读自己的 2021 年终总结来鞭策自己。今年由于家里的特殊原因需要在医院过年,时间比较仓促,勉强抽出了一天的时间来简短写写年终总结。一方面是给 2022 年的自己一个交代,另一方面也是给 2023 年的自己一个警醒。希望我的经历和感悟能给大家一些启发。

首先依然是自我介绍环节,我叫谭新宇,清华本硕,现在清华大学软件学院 Apache IoTDB 组就读研三,师从王建民/黄向东老师,我对共识算法,分布式存储系统,时序数据库和分布式事务都比较感兴趣。

接着简单介绍一下我们组的工作:Apache IoTDB(物联网数据库)是一体化收集、存储、管理与分析物联网时序数据的软件系统。Apache IoTDB 采用轻量式架构,具有高性能和丰富的功能,并与 Apache Hadoop、Spark 和 Flink 等进行了深度集成,可以满足工业物联网领域的海量数据存储、高速数据读取和复杂数据分析需求。

2022

介绍完背景之后,在这里回顾下 2022 年的经历。

2 月,Apache IoTDB 社区的新分布式架构设计正在整个社区的努力下如火如荼的进行着,社区针对分布式时序数据库架构的方方面面都进行了广泛的调研和讨论,我也很幸运地参加了若干模块的调研设计,收获良多。对于分区方式,我们结合一致性哈希和查找表的优缺点,选择了一个更符合时序场景 trade-off 的分区方式,既不引入较大的存储成本,又具备一定的负载均衡灵活性,而且还留有足够的扩展性。对于扩展能力,我们将时序元数据与时序数据等同来看都做了多分片,使得集群拥有很强的横向扩展能力。对于查询引擎,我们调研了 Trino/Impala/Doris 等系统的 MPP 框架,又基于我们对时序场景的理解设计出了针对时序场景特殊优化的 MPP 框架和 Pipeline 执行引擎。对于共识算法,我们观察到不同的业务对于共识算法一致性和性能之间的 trade-off 有不一样的倾向,开始思考并着手设计一个能够支持不同共识算法的通用共识框架。

2 月下旬,在为 Talent Plan 社区提交若干代码修复并做了 3 次有关共识算法和分布式事务的公开分享之后,我荣幸的被 Talent Plan 社区接纳为了 mentor,期待以后能够继续和志同道合的小伙伴在 Talent Plan 社区沟通交流。

3 月,需要毕设开题的我结合 Apache IoTDB 新分布式架构对通用共识框架的需求,开始调研学术界和工业界在通用共识框架领域的相关工作。在调研中,我发现了 Facebook 的 Delos 框架不仅支持在一套接口下实现不同的共识算法,还能够支持生产环境动态变更共识算法,他们的工作也得到了学术界的认可,成为了 2020 OSDI 的 Best Paper。沿着他们的思路,在摒弃了当前 ROI 收益较低的生产环境动态变更共识算法后,我便开始着手设计通用共识框架的接口,该框架不仅需要先支持强一致性的 Raft 算法和弱一致性的异步复制共识算法,还需要为未来更好更丰富的共识算法接入留下扩展性(例如 2021 FAST 的 Best Paper 就是基于异步复制的思路在提升写性能的同时又在读时添加了一些约束,从而提供了跨客户端单调读一致性,基于 ZK 实现后相比 ZK 性能能够提升 1.8-3.3 倍)。由于这个思路在学术界和工业界都相对新颖,我的开题便较为顺利的被通过了。

3-4 月,由于毕设开题读了一大堆论文状态比较好,我开始在知乎上回答自己感兴趣领域的很多问题,并幸运的在最开始就得到了很多赞,这些对我的认可又成为了我进一步在知乎上学习和活跃的动力,从而形成了一个正反馈效应。正如去年年终总结的感悟中所提到的,这种正向反馈对于我自己的激励作用是非常大的。现在回过头来看,那段时间尽管我也有一些输出得到了很多赞,但收获最大的还是在此过程中阅读了知乎上分布式系统领域非常多的优秀回答,学到了很多技术知识,了解了很多思考维度。

4 月,忙完毕设开题的我开始面试暑期实习,尽管八股和项目由于日常的积累都没有什么问题,但由于实在提不起兴趣和动力刷题,所以在面试过程中还是多少有些磕磕绊绊。幸运的是最后投的几家公司除了微软之外总体都面的不错,最后思考再三后还是选择去 PingCAP 实习。一方面是 PingCAP 的三轮面试官(赵磊老师,徐锐老师,金鹏老师)给我的面试体验都非常好,另一方面则是我一直对 PingCAP 的很多体系(例如工程服务体系,架构演进体系,开源体系等等)非常敬佩和好奇,想要借此机会去学习感悟。

5-6 月,我专心投入到了 Apache IoTDB 新分布式框架的实现中。最主要的工作便是通用共识框架,这期间一方面抽象了其对上对下的通用接口,另一方面则是为其支持了若干共识算法。对于强一致性共识算法,我调研了 Java 实现的若干 Raft 库的成熟度,并最终得出只有 SofaJRaft 和 Apache Ratis 可以使用的结论。基于此结论,我和子阳探索了 Apache Ratis 的实现并将其集成到了我们的共识框架中,这使得 Apache IoTDB 的新分布式架构具备了强一致性的能力(这半年以来,子阳在 Apache Ratis 的稳定性和性能优化上投入了大量的精力,令人开心的是目前他已经得到了 Apache Ratis 社区的认可,成为了 Committer,可以说是双赢了)。对于弱一致性共识算法,我们结合时序场景写写冲突极少的业务特点,设计并实现了基于异步复制思路的弱一致性共识算法 IoTConsensus。我和乔老师,恺丰,海铭,金瑞,洪胤,厚亮和珍姐都参与了 IoTConsensus 的设计实现与迭代测试。IoTConsensus 做了非常多的工程优化,包括但不限于 Batching,Pipeline,Thrift AsyncClient/AsyncServer 等等,所以流程非常复杂。虽然实现和 debug 的过程非常艰苦,但我们在异步编程,内存控制,可观测性,debug 技巧等方面都有了显著的进步,可以说是既痛苦又有收获吧。此外,为了兼容统一的共识框架,避免单副本时共识框架的额外开销,我们还专门针对单副本的场景(只需要 scale out 而不需要 high availability 的场景)设计了极为轻量的 SimpleConsensus,避免出现 RaftLog 和存储引擎 WAL 双写的现象出现。在未来,我们还计划为 Apache IoTDB 的共识框架加入更多的共识算法实现,例如 SofaJRaft 和我们组今年中的 ICDE NB-Raft 等等。我非常期待 Apache IoTDB 共识框架的文档,功能,性能,稳定性和正确性等等都能够迅速成熟,甚至可以成为大家未来使用通用共识框架的范式,这样如果业务上对共识算法一致性和性能的 trade-off 有不同的需求,便可以直接使用我们已经封装好的共识框架而不用再去造轮子了。这里也非常欢迎对共识算法感兴趣的同学一起参与进来~

7-10 月,我在 PingCAP 进行了全职实习。在 PingCAP 的暑期实习是我个人体验最好的一次实习。在技术上,我不仅可以去学习公司内部海量的技术积累(Rust,分布式数据库,TiKV,调优培训等)和流程规范(如何建立可扩展的工程服务体系和可持续的架构演进体系 -> 可观测性 + 分级 Support && 业务场景持续打磨),也可以系统学习 TiKV 事务引擎演进的历史(乐观事务->悲观事务->大事务->Async Commit/1PC-> 悲观事务内存悲观锁等)来培养自己的产品思维,最后还可以基于这些成长去做一些深入的探索并取得了不错的成果。在生活上,同事们会非常耐心友善地回答我的种种问题,工程经验十分丰富的 mentor 徐锐老师也花了非常多的时间和我 one-one 沟通我的种种疑问来帮助我快速成长(技术问题。如何平衡技术驱动和业务驱动?如何评估架构演进和工程服务的 ROI 等等),金鹏老师和 HRBP 也会和我定期沟通最近的工作进展。PingCAP 是国内开源数据库和开源社区的佼佼者,非常推荐大家有机会前去实习,一定会不虚此行~

8-10 月,我海投了很多感兴趣的数据库团队,并以没有任何职业背景的身份参加了 41 场秋招面试。虽然非常忙碌,但这些面试尤其是终面加面环节对我技术的成长和产品思维的提升有很大的帮助。在面试过程中我也有幸认识了很多大佬,并幸运地拿到了不少 offer,在这里表达对相关面试官和 HR 的真诚感谢。

10 月中旬,我被评选为了 2022 软件学院科研科创年度人物,这令我诚惶诚恐。在我看来,这个奖项更适合论文发到手软的大佬。询问之后发现现在的评审规则中也包含了开源贡献,所以现在做系统做工程的同学也可以得到学院的认可。在这里也真诚感谢学院对我的认可。

10 月下旬,我和祥威洪胤子阳参加了 2022 TiDB Hackathon,并最终拿到了产品组的最佳校园奖。在这次 Hackathon 中,从技术上我们为 TiKV 做了 Parallel Apply 的优化 Demo;从产品上我们在高并发批量写入热点场景会有不错的收益。我们模拟了银行清算结算等跑批业务的极致情况,在 60 并发下,不同 BatchSize 的批量写入性能提升 89.4%~119.0%。TiKV CPU 利用率从 700% 左右提升至 1500% 左右。我们也尝试了通用的批量导入热点场景,对于 TPCC prepare,在 1024 BatchSize 下,不同并发批量写入性能提升 29.8%~36.0%,TiKV CPU 利用率也从 750% 左右提升至 1000% 左右。通过这次 Hackathon,结合 OB 4.0 版本自适应日志流的设计,我们对 Raft 和 Multi-Paxos 的异同有了更深刻的理解。总体而看,一个系统的架构设计就是要在关键模块的各种 trade-off 中做出纠结的选择,并且一旦做出了某个选择,就需要基于这个选择更进一步做非常多的产品化工作和优化打磨来提升这些技术对于用户的实际价值。例如,TiDB 选了 TSO 的时间戳获取方案并不代表就不能服务跨数据中心场景了,其也做了 Local/Global TSO 的产品化工作来满足部分用户场景的跨数据中心需求。CRDB 用了 HLC 之后并不仅仅体现在获取事务时间戳更快,其至少还基于 HLC 在 Strong/Stale Follower Read 这一块做了许多工作来减少跨域流量从而降低成本。对于 OB,其选择了 Multi-Paxos 而不是 Raft,并且更进一步在 4.0 架构中提出了单机分布式一体化架构来解决其他数据库很难彻底解决的写热点缓解,大事务支持和 1PC 比例增大等难点。当然,这些技术和产品化的工作短期内很难形成事实标准,也都能够在各自的用户场景产生价值,至于孰优孰劣就很难客观判断了。

11 月,我手上的秋招 offer 陆陆续续开奖了,这期间涉及到了非常复杂的心理变化。有期待,有失望,有惊喜,有反思,有迷茫,有透彻。对于最终选择去哪里,我纠结了许久,请教了很多朋友,前辈,同学,师兄,父母和导师的意见。其实选择哪条路都不会太差,主要还是需要剖析自己更喜欢怎样的工作方式,并且说服自己一旦做出选择后就不再患得患失。此外王老师东哥乔老师都对我的就业方向和未来发展路径给予了中肯的建议,最终我选择了 Apache IoTDB 的商业化公司天谋科技继续做 IoTDB。我非常感谢研究生期间 IoTDB 这个大平台对我的帮助,也希望自己未来能够继续在这个大平台发光发热。

12 月,Apache IoTDB 的 1.0 版本发布了,这次新版本凝聚了整个社区的智慧和力量,标志着 Apache IoTDB 从此彻底拥有分布式,为后续产品快速发展奠定了良好基础。这次分布式 1.0 架构的发布也是促使我决定留下的重要原因之一,因为我觉得这个架构有太多可以做的工作可以去做,一些积累的技术宅已经还清,我相信未来 Apache IoTDB 一定能够在工业物联网的时序场景大放异彩。想通以后,我也和洪胤子阳湘鹏组成了系统优化小组,不断扩大我们的 scope 去和 IoTDB 一块成长了~

今年我在 Apache IoTDB 社区 Review 了 187 个 PR,提交并被合并了 48 个 PR。今年的工作有很多新颖的东西,希望明年能够继续保持下去。

今年我在知乎上写了几十篇博客和回答,粉丝数和点赞数相比去年同期有了接近 10 倍的增长。Github 上的 Follower 数和个人仓库 Star 数也有了 6 倍多的增长。希望自己明年还能继续坚持输出有价值有意思的知识。

今年我看了权谋剧的巅峰之作《大明王朝 1566》,尽管剧中演绎的是封建社会,但其中一些社会运行的本质规律放到今天也依然适用,我自认为受益良多,非常推荐大家去看。此外我也读了 IT 人的必读书籍《浪潮之巅》,了解了信息革命以来很多著名公司的兴衰更迭及背后的哲学原因。天下大势,浩浩汤汤,顺之者昌,逆之者亡。不论是公司,组织还是个人,自己的努力不可或缺,但只有抓准大势站上浪潮之巅,才有可能干一番大事。

一些感悟

介绍完了 2022 年的经历,在这里谈谈自己这一年的新感悟,这些感悟不一定适用于每个人,但都是我个人在今年得到成长的诀窍。

没有不写 bug 的人,但要成为追求不写 bug 的人

这一年在日常的开发过程中修复了无数的 bug,一些是陈年老 bug,一些则是自己在开发过程中引入的新 bug。这期间我一直在思考为什么会有这么多的 bug?什么时候能够修复完所有的 bug?现在我有了更明确的感悟:

对于一个 bug,从设计->编码->UT->IT->压力测试->混沌测试->发版测试->用户 POC 环境->用户生产环境这套全链路的流程中,越晚被发现,则修复的成本就越高。世界上没有不写 bug 的人,也不存在没有 bug 的系统,我们需要尊重这一客观规律。出现 bug 不可怕,但不对其进行反思改进就非常可怕了。虽然没有不写 bug 的人,但要成为追求不写 bug 的人,因为只有具备了这个追求,才会在日常的开发过程中注重 bug 产生原因的积累,并通过种种技术手段来规避 bug 的产生。正是因为对 bug 的反思,学术界和工业界才产生了很多对系统稳定性至关重要的工作(形式化验证,确定性模拟器,混沌测试,持续集成等等)。一个工程师的成长必然伴随着对种种异常情况的考虑,知识边界被拓宽后自然写出 bug 的概率就会越来越低。

新的系统,新的模块,新的引擎,新的算法需要一段时间的稳定性打磨,没有用户去用就很难成熟,但如果用户去用了,团队也一定要利用好这次机会,让产品的稳定性和工程师的能力一起成长,进入一个正反馈循环才有可能让产品越来越好。

性能优化与代码可维护性需要有一个平衡

一般而言,复杂的性能优化往往会导致代码维护成本的上升。例如事件驱动的并发编程模型具有更高的自主性,性能上限相比完全被 Runtime 接管的协程可能会高一点,但带来的回调地狱问题又可能会大幅增大代码复杂度,导致代码维护成本大幅上升。从全局的 ROI 评估来看,这样的工作不一定收益很高。

今年我在开发 IoTConsensus 过程中就有点过于追求性能优化,加了一堆异步逻辑和工程优化,虽然优化完后性能还不错,但这种代码上的复杂度也使得大家在 debug 时非常痛苦,新人也比较难一下子看懂主要逻辑,只能靠进一步完善文档细节并做代码走读才有可能让新人逐渐上手。

在未来的工作中,我也会吸取这次的教训更关注性能优化与代码可维护性之间的平衡。

有太多能力可以提升,不要只看到技术

今年在实习和秋招面试过程中有幸和非常多的技术大佬有过交流,在他们身上技术能力只是一个值得学习的维度,其他维度的能力还包括管理,演讲,分享,社交,营销,商业感知,为人处世等等。

要想进一步实现职场的抱负,综合能力是十分重要的。总之,有太多领域的太多能力可以去提升,技术只是其中比较重要的方面之一,最好不要仅仅把自己拘泥在技术上。

不断扩展自己的 scope,锻炼培养自己的综合能力,便能在单位时间内获得更大的成长拥有更丰富的阅历,从而可能在机遇出现时顶住压力抓住机会。

技术是满足业务的手段,一定要带有产品思维

技术最终是要为业务服务的。没有业务侧的需求,技术最终也难以发挥实际价值走向成熟。

在做日常的功能开发和性能优化时,最好能够带着产品思维去思考问题:自己所做的工作在整个产品中处于怎样的一个位置?做了这个工作之后整个产品会有什么样的不同?一旦能够培养出来这种端到端的产品思维,自己也会更明确工作目标并更有动力去做事成长。

针对不同硬件环境和业务负载的排列组合,有太多有意思的工作可以去做

刚入门数据库的时候一直比较好奇,像 Oracle 这样的数据库厂商是如何每年都有那么多新的工作可以做?为什么我就想不到做那些呢?

通过在 Apache IoTDB 实验室的成长和在 PingCAP 的实习,我理解了业务驱动对于产品的意义。只要有用户和业务的支持,就会有源源不断的需求出来。对于数据库系统而言,在不同的硬件环境和业务负载下,有太多的功能和性能优化可以去做,几乎不存在技术上没有事情可做的情况。当然,任何组织任何个人所能调度的资源都是有限的,如何评估当前所有工作的 ROI,如何在有限的资源上持续的做紧急重要且正确的事,也是产品成败存亡的关键。

好的系统需要在天花板高的架构设计上进行日复一日的持续打磨

OceanBase 的杨传辉老师提过一个观点:每个系统设计时都需要考虑架构、稳定性和性能,这三者之间的关系是什么?一个经典的规律是“把稳定的系统做高效,远比把高效的系统做稳定更容易”。最难的是从 0 到 1 把系统做稳定。有了稳定的系统,接下来逐步优化性能往往会比较顺利,直到遇到系统架构的性能天花板。因此,系统架构设计之前,首先要考虑清楚系统的目标和性能天花板,接着基于正确的架构把系统做稳定,最后优化性能。

在 PingCAP 的暑期实习期间我很明显的一个感受就是,TiDB 的可观测性做得非常好,同事们都比较明确特定业务场景下当前 TiDB 的短板在哪里,也明白自己工作的端到端价值,从而能够持续打磨 TiDB 在特定业务场景下的性能。大家的工作并行汇聚起来便能够促使 TiDB 每个版本都能够在很多业务场景下有不错的进步。

在现在的我看来,Oracle 最有价值的东西其实是在当前的市场规模下能够接触到最多最复杂的业务场景,从而能够持续的对系统进行打磨,这是其他任何单机数据库都没法做到的,自然也就无法在单机数据库领域打败 Oracle 了。

在系统初期,调研设计出一个性能天花板高的系统架构非常重要。在系统搭建完成基本稳定之后,在业务场景下进行持续的打磨就更为重要了。比如 Apache IoTDB 1.0 的分布式架构性能天花板我自认为就很高,目前性能也基本打磨到了和 0.13 版本一致的地步,下一步就是在特定业务场景下进行持续打磨做稳定性和性能的进一步提升了。

提出问题比解决问题更为重要

好奇心是人类进化创新的驱动力。发现当前存在的问题,才有可能去进一步改进解决。爱因斯坦早在《物理学的进化》中就说过:”提出一个问题比解决一个问题更为重要。 因为解决一个问题也许是一个数学上或实验上的技巧,而提出新的问题,新的可能性,从新的方向看旧问题,则需要创造性的想象力,而且标志着科学的真正进步”。

对于数据库系统,在特定硬件环境和业务负载下,性能瓶颈到底在何处?若想优化当前最大的性能瓶颈,它到底是一个工程问题还是学术问题?如果是工程问题,需要投入多少资源去完成?会有多少收益?如果是学术问题,它的 trade-off 到底是什么?有什么更符合当前业务场景的可能性吗?一旦有了这样思考问题的方式,就会发现技术上其实存在很多可能。

个人的努力不可或缺,但平台和机遇往往更为重要

在看了《大明王朝 1566》 和《浪潮之巅》后,越发认识到时势造英雄的客观规律。个人的努力能够决定个人的发展下限,但平台和机遇才能够决定个人的发展上限。很多时候,玄而又玄的天下大势和因缘际会反而可能会在若干年后造就一番佳话。

就目前而言,认识到平台的重要性,学会顺势而为,在职责范围内乐于沟通踏实做事,可能是个人职业生涯短期的最优解了吧。

没有绝对的成功,以个人最舒服的姿态和最擅长的方式去活一生就已足够

对于个人而言,绝对的成功很难定义,技术和商业也仅仅是很小的一部分。在认识到时势造英雄的客观规律后,我愈发觉得精神上的富足对于一个人一生的幸福最为重要。有一句话叫做”但行好事,莫问前程”,没有必要去和其他人比来比去,任何人都是比上不足比下有余,能够以个人最舒服的姿态和最擅长的方式去活一生就已足够,剩下的交给命运即可。

多站在别人的角度思考问题

在日常工作中,很多时候会涉及到任务的分工与合作,这就需要频繁地沟通。

每个人都有完全不同的成长环境,不同的成长环境造就了不同的三观以及思维方式,进而产生出不同的职业动机和职业规划,最终使得对待工作的态度和动力也会有所差别。这些差异无关对错,但有时候过于从自己角度思考问题并进行沟通反而会适得其反。

在与他人沟通时,如果能够站在别人的角度去思考问题,懂得换位思考,则很多矛盾在沟通过程中就可以被缓解甚至解决。当然,有些天然对立的矛盾是没办法彻底解决的,只能选择一个平衡点进行缓解。

来年展望

今年的年终总结写的比较仓促,但也算是勉强写完了。

新的一年就主要聊聊与 Apache IoTDB 有关的技术展望吧:

  • 共识框架:功能,性能,稳定性,正确性和文档稳定推进,希望能够吸引感兴趣的同学加入进来~
  • 可观测性:深受 TiDB Performance Overview 面板的影响,下一步计划大幅加强 Apache IoTDB 的可观测性,并基于此来建立可扩展的工程服务体系和可持续的架构演进体系。
  • Java 全异步执行框架:暑期在学 Rust 时就已经被其 async/await 的无栈协程设计所折服。对于 Java 来说,自带的有栈协程框架 Loom 刚刚 GA,离正式生产环境用到还很久远。事件驱动的回调机制尽管性能很好,但回掉地狱的出现又会极大的影响代码可读性和可维护性。这一块在调研很多 Java 实现的大数据栈后并没有查到相关的资料。幸运的是,通过对 CompletableFuture 和 Thrift AsyncServer/AsyncClient 接口和源码的探索,对于如何基于 Thrift 的 NIO 机制来提升性能又利用 CompletableFuture 的编排能力提升代码的可读性可维护性,我已经有了一些想法和探索,期待明年能够结合这两者的优点进行一些 Java 数据库下 SOTA 线程模型的探索论证和实现测试,并形成系统性的博客向社区输出。

最后,感谢您的阅读,希望这篇总结能够对您有所帮助。

在除夕这天,预祝大家新年身体健康,阖家幸福,心想事成~


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!