维护万星开源向量数据库是什么体验
“亲爱的小凡,恭喜成为 Milvus 项目的 Maintainer!作为 Milvus 社区的维护者,这个角色拥有许多权利:小到提交和审核项目代码,大到主导社区日常的运营工作,甚至是对整个技术项目的技术路线进行决策。但与权利相对的是更大的责任...”——《Milvus Maintainer Invitation》这是我十年来最勇敢的决定。在加入创业公司、参与开源社区一年...
“亲爱的小凡,恭喜成为 Milvus 项目的 Maintainer!作为 Milvus 社区的维护者,这个角色拥有许多权利:小到提交和审核项目代码,大到主导社区日常的运营工作,甚至是对整个技术项目的技术路线进行决策。但与权利相对的是更大的责任...” ——《Milvus Maintainer Invitation》
这是我十年来最勇敢的决定。
在加入创业公司、参与开源社区一年之后,我成为了 Milvus 社区 [https://milvus.io] 的 Maintainer,收到了上面的邀请函。除了梦想成真的喜悦,也不由得为这一路的酸甜苦辣而感慨。也对 “纸上得来终觉浅,绝知此事要躬行” 这句话有了更深刻的体会,这一年以来的开源项目维护经历,教会了我想要维护好一个开源社区绝不只靠热情,更需要“体力”、“脑力”和“心力”。
在我选择投身 Milvus 开源社区,加入这家创业公司之前,我曾经做过三次非常重要的决定:第一次,是毕业后加入 Oracle,决定从事数据库相关的工作;第二次,是追随 Cassandra 创始人 Avinash 加入一家软件定义存储创业公司 Hedvig,深入了解如何设计和实现分布式系统;第三次,是决定回国加入阿里,构建一款自主可控的云原生多模数据库 Lindorm。幸运的是,虽然这三次选择都是困难模式,但都收获颇丰,让我的人生观和技术观都得到了进一步的完善。
在决定开启一段新的征程之前,我曾扪心自问自己到底想要什么,在经历了之前种种之后,新的答案跃然纸上:我看到了AI 时代非结构化数据爆发式增长的新机遇,想在这条新赛道上,从零到一地做一款面向 AI 的数据库产品、做一个自己工程师生涯的代表作。于是我毅然放弃了百万年薪和熟悉的老赛道,开始追寻自己的开源理想和技术抱负。
如果你想了解如何维护一个开源社区,或者你也像我一样,希望加入一个有意义的开源社区,提升自己的技术影响力,做难而正确的事来帮助更多的人。或许接下来,我要分享的内容可以帮助到你,让开源路上的朋友们少走一些弯路。
开源维护者101 - 体力篇
作为一个活跃的开源社区的维护者,最难的事情莫过于日复一日程式化的操作,我的每一天几乎是从浏览邮件和清理 Github 通知 [https://github.com/milvus-io/] 开始的。有时因为出差一天,而没有及时清理消息,Github 的通知界面就会变成下面这个样子,这对于有“红点消除强迫症”的我来说实在是一个灾难。
Github 带来的不仅有数量惊人的站内通知和邮件提醒,也包含大量令人费解描述的 issue、discussion,包含常见报错的重复提问,不符合项目 CI 质量要求和没有遵循流程规范的 PR 贡献提交,以及一大堆日常琐碎的项目仓库相关的管理事务。
在大量的尝试中痛苦挣扎后,我摸索出了一些能够帮助到开源项目开发者的方法。
一、重视文档的维护
好的文档能减少大量无意义的重复工作,所以请及时更新你所维护项目的文档。
务必检查你的开源项目中是否包含一个有意义的 “README.md”,并确认这个文档中,有清晰的介绍你的项目愿景,以及用户开始使用和贡献项目所需的信息。
维护一个好的 “项目路线图”,以便让用户知道他需要的功能会在什么时候发布。同时,也能够方便贡献者快速找到自己感兴趣和适合的内容进行贡献。
公开社区的基本规章制度和运营规范,比如 “DEVELOPMENT.md” 可以帮助新加入的同学了解开发流程,“CONTRIBUTING.md” 让贡献者可以清楚的了解到贡献流程和审查规则,“MAINTAINER / CONTRIBUTOR” 列表文件,能够帮助人们找到可以寻求帮助的社区成员。
及时更新的用户文档和技术架构文档,可以大幅降低解释成本。在社区用户遇到常见问题时,我通常会鼓励用户自己查阅项目文档,通过自己的力量找到想要的答案。
二、重视自动化
自动化的部分越多越好,代码胜千言。
重复且不需要创新的工作,可能自动化,比如 Prow 可以帮你节省大量 GitOps 相关的工作,Mergify 可以做规则检查,自动合并代码。
我们之前项目的代码覆盖率很低,在引入 Code Coverage 并完成代码覆盖率最低限制之后,项目的覆盖率很快就提高到了 80% 以上。
当我们在项目中引入 Golint 后,它帮助我们完成了项目中 Go 的代码风格统一。当然,也导致我们花了几周的时间,进行集中的问题修复。随后,在大量参考 Uber 的 Go 语言开发规范 ① 之后,我们针对代码提交信息格式也进行了比较严格的要求。
此外,我们还利用 Github Action 构建了 CentOS、Ubuntu、MacOS、MinGW 这几种不同系统的开发环境,让 Milvus 能够进行自动的多平台编译和自动化测试。
三、学会拒绝
开源维护者要学会说不。
或许人的本性是做加法,然而增加一个不成熟的功能,或者接受一个不符合社区规范的 PR,通常不能够帮助社区变得更好。
在接受一个来自社区贡献者的功能之前,不妨先问问自己:“这个贡献内容是否符合社区的代码规范”?“是否遵从项目的设计初心”?“满足自己的技术审美”?“是否真的优雅高效”?
当项目中出现了许多“不知所云”的 issue 或者质量不达标的 PR 贡献时,不妨思考你是否向用户和开发者们提供了良好的 issue 或 PR 模版,让参与者有例可循。
如果你的项目还没有使用过 “GitHub 模版” 功能,我强烈建议你试试看。我在上文中有提到过,优先建立清晰的规则。
当用户和开发者出现问题的时候,也请立刻向贡献者指出问题所在,他到底违反了哪一条规则,并向他提出改进方案或者发送给他相关的文档参考。
开源维护者102 - 脑力篇
只是投入大量体力并不能够成为一个合格的开源项目维护者,更重要的是要不断进行思考并沉淀如何将项目价值最大化的方法论。
方法论
我认为,一个好的开源项目首先必须具备其独特的价值,最好是能够在 README 中的第一句话中就有所体现。
以 K8s 社区举例(README ② 中的第一句话):
"Kubernetes, also known as K8s, is an open-source system for automating deployment, scaling, and management of containerized applications."
上面的二十来个单词,简洁明了的向用户说明了项目要解决的问题。一个开源社区的维护者,必须反复思考项目对用户的真正价值所在,并不断进行沉淀,精炼出符合社区用户预期的愿景。
当项目有了一个足够清晰的愿景之后,接下来最迫切的事情就是开发出解决用户场景问题的 MVP 产品。而定义什么是 “最小功能集” 同样考验开源维护者的智慧。我们就曾在这个环节中踩了大坑,在启动 Milvus 2.0 项目时,我们制定了过于宏伟的目标,以至于在整个 2021 年中,开发团队都深陷于修 Bug 和重构的泥潭中。
多数情况下,开源项目想要获取成功,在起步时往往应该选择利基市场,以较低的代价解决一个小的用户核心痛点,并在这个基础上去持续扩展迭代,而非过度追求大而全和形式的优美。推荐阅读《RethinkDB:为什么我们失败了》这篇文章,文章从一个 CEO 的视角解释了准时交付最小功能集对于一个开源基础设施产品而言有多么的重要。
在项目迭代的过程中,社区的开发流程经过不断的思考和讨论被逐渐完善。这里要由衷的感谢 @yanliang567 ③ 同学,他作为社区的质量担当承担了大量细致的工作拆解和任务规划:从第一个预览版到 2.0 正式版发布的过程中,我们一共经历了多达 8 个 RC 版本,每经历一个版本,我们的软件质量指标就愈加清晰。
在这个过程中我们逐步提升压力测试的数据量、持续时长、并增加了混沌测试、滚动升级测试和数据兼容性测试。每个阶段目标的达成,都为我们提供了非常多的正向反馈,极大的提高了开发团队对于产品朝着“稳定可靠、安全快速”目标进军的信心。
在这个过程中,社区的开发流程同样经历了逐步思考和完善,得到了一个高效的火车发布模型:每年发布一个可靠的主要版本,每三个月发布一个大版本,每两周发布一个 bugfix 版本。完整的工作流程如下:
当每个版本的维护期临近结束时,由社区 Maintainer 组织会议,维护者一起讨论下一个版本中需要发布的功能,以及确认版本发布的具体时间点。
当项目新的里程碑制定完毕之后,由团队成员和社区的贡献者认领功能,制定靠谱的开发计划,完善 Milvus Enhancement Plan 并在社区技术会议中发起讨论。这个阶段也被称为 Debt Week,除了完成新功能设计的讨论,我们也会集中修复上个发布中引入的一些技术债和 Bug。社区严格遵守 “文档先行” 的原则,认领功能的开发者除了要实现代码之外,也需要维护和设计好“文档”,以便我们后续能够进行一系列测试、用户能够有一份清晰的功能使用文档。
在紧张的开发过程中,每个功能的开发负责人需要每周进行项目进度对齐,并根据优先级和实现状态调整功能“上车”还是“下车”。
版本开发周期的最后一个月,我们通常会选择冻结代码,为为 QA 团队拉出一个用于测试的分支。在这个月里,我们也会集中精力优先解决之前没有解决完毕的、优先级比较高的 Bug,当 Bug Triange 团队判断软件已经解决掉了所有阻塞发布的 Issue、判断质量能够达到发布标准后,软件就能够发布与用户见面了。
我个人认为类似这样的“火车模型”,对于开源社区这种组织相对比较松散的团队是非常合适的。能够极大的减少因为“人的单点”造成项目发布被阻塞的问题。事实上,维持一个相对频繁的发布节奏,对于项目的在 GitHub 平台上的活跃度也会有帮助,每当我进行版本发布的时候,都能够看到 GitHub 仓库和 Docker 镜像的下载量出现一个比较明显的提升。
开源社区运营
在这个小节的最后,我想聊聊关于开源社区的运营。
很多工程师背景的同学都更加关注开源项目代码本身的价值,而容易忽略了“文档、社区运营、好的 Demo” 这三块为项目带来的巨大的价值加成。
在我学习开源运营的过程中,夜天之书公众号 ④ 和《销售加速公式》⑤ 这本书带了我很多新的思考,如果你对开源运营感兴趣,欢迎一起讨论交流。
这里,我分享三个关于开源运营的小心得:
1. 不仅要面向数据运营,更要面向正确的数据运营
关于是否需要为开源社区运营搭建指标体系,在社区和公司内部都经历过激烈的讨论,我本人是数字化运营的忠实拥护者。个人观点,不只是开源运营,对于任何 “inbound” 的触达方式,建立好的用户漏斗都是获客的不二法门。
在目前的 Milvus 社区用户体系中,也包含了这样的一个模型:
面向不同类型的社区参与者,我们应该提供的帮助是不同的。
比如:针对初级用户应该提供更加友善的接入文档和 Bootcamp,帮助用户能够在半小时之内真正将产品跑起来,判断项目能否解决他们的问题;而面向深度用户,则更应关注微信群是否活跃、Github Issue 能否在当天获得回复,社区有没有足够多的优质技术文档去帮助他们了解技术细节,项目中有没有足够的辅助工具帮助他们完成监控、日志收集、数据迁移等常见需求;对于贡献者,Milvus 社区推出了 Mentorship 项目,通过“老带新”的方式来建立新贡献者与老贡献者之间的连接,帮助他们快速融入项目,更快的完成自己想实现的目标;最后,对于深度贡献者,社区则应该建立更加完善的荣誉体系和激励机制,包括但不限于 Membership 机制,在发行说明中明确的对贡献者进行致谢,当然也可以通过饱含情意的小礼物来感谢贡献者。
我个人建议针对社区的不同阶段,尽量选择不同的、合理的量化指标,使用适应社区发展阶段的指标体系对社区的决策会有很大的帮助。
尽管 “Star” 的数量是非常重要的量化指标,经常被用来衡量一个开源项目的受欢迎程度,但过度关注这一指标会导致漏斗长期停留在获客的初级阶段,丧失了对激活、留存和最终转化等更重要内容的关注。因此 Star 这些相对简单的数字指标绝不应该是开源项目维护者重点关注,甚至是唯一关注的数据指标。
2. 在正确的阶段,做正确的事情
管理大师彼得.德鲁克曾指出:“效率是以正确的方式做事,效能是做正确的事情,对企业而言,不可缺少的首先是效能”。事实上,对于社区而言,只要不偏离项目使命,不违背开源精神,面向用户出发,绝大部分事情方向都是正确的。真正的效能挑战在于面向社区所处的不同阶段,如何制定正确的执行计划。
举个例子,我们曾经自建的 Milvus 论坛的上线,对于社区运营而言就是一个比较失败的尝试。建设论坛的初心是我们希望能够通过论坛的形式将用户在 Slack 和微信中讨论的、难以沉淀的知识进行整理和公开。因此在借鉴了 TiDB 社区的 AskTUG 的成功经验之后,我们也上线了 Milvus 社区自己的论坛。然而这个论坛并没有获得想象中的良好反馈,甚至连 Milvus 的 Maintainer 团队也很少使用论坛进行交流。
事后复盘来看,社区运营不应该简单的“抄作业”,而应该因地制宜。两个社群的用户群体、用户数量,包括维护者都存在着差距,简单搭建一个论坛的形式意义超过了实用价值。况且 GitHub Discussion 和 Slack 已经可以很好的满足用户提问讨论的核心需求,其实并不需要额外引入新的形式。
3. 简单的流程才能持久
制定社区流程同样是社区管理者的核心工作,但首先要明确的是社区并非由冰冷的代码和文件组成,流程最终服务的对象是“人”,也就是社区成员和社区用户。
在没想清楚某个流程的意义之前,不要着急引入任何新的流程,而是需要问自己几个问题:
第一,流程的目标和参与者是否明确;
第二,针对流程的每个步骤有没有明确的目标;
第三,是否明确了社区参与者对于这件事情的期待和反馈?比如在提交流程中开发者的期待是什么?reviewer 的期待是什么?CI/CD 的维护者期待又是什么?
要切实保证流程能被每个环节的参与者切实执行,而非成为摆设或者参与者贡献的阻碍。
简单的流程带来的好处是执行和遵守的成本会大幅降低,收益会大幅提高。我曾经阅读过近 60 页的阿里巴巴开发手册,试图向团队的成员推广,事实上收效甚微,甚至我自己作为 reviewer 也不能写出完美符合开发手册的代码。相比之下,更靠谱的方式是能寻找或者定制一个能够检查代码风格、并根据规则自动判断代码能否进行合并的 IDE 插件,将整件事完全自动化。
关于流程,简单带来的一个更加明显的好处在于可迭代性。好的流程是用出来的,需要持续的宣传并鼓励大家遵循,也需要有专门的维护者持续关注流程是否在正常运行。简单的流程可能在应用初期会有“漏洞”(缺失了一些场景的覆盖),但是却便于维护者不断补充细节,而过于复杂的流程容易让我们陷入形式主义丧失做这些事情本身的初心。
开源维护者103 - 心力篇
关于开源维护者的心理建设,我想没有哪篇文章比《How to Use Open Source and Shut the Fxxk Up At the Same Time》⑥ 一文中介绍的更清楚了。开源项目由于其开放性带来了高传播度,不仅仅给开源项目维护者带来了技术影响力等正面影响,也带来了很多意外的困扰。
作为开源项目贡献者,很难完全忽略社区的发出的声音,尤其是在项目维护的过程中,会频繁遇到大量伸手党的对于稳定性、性能的抱怨、对于各种各样定制功能的要求。在技术路线决策期间,维护者需要一次次的跟不同认知水平的用户去介绍 when、why、what 和 how 这一系列的问题。这些问题也曾在很长一段时间内困扰着我,慢慢蚕食着包括我在内的维护者的耐心,好在总有善意的用户在我们最需要的时候,给我们鼓励,为我们打气,让我们做觉得一切付出都是值得的,让我好像找回了自己做开源软件的初心:
作为开源贡献者,始终保持气度和友善的态度是一门终身必修课。学会坦然面对各种批评和抱怨,辩证的看待所有正面和负面的评价,不论观点正确与否都能做到就事论事的讨论,是我这一年来收获的最大的成长。鲁迅先生曾说 “人生得一知己已足矣,斯世当以同怀视之”,能够在社区找到三两世界观、价值观、技术观高度趋同的小伙伴,已经是我作为开源贡献者最大的快乐,毕竟我们的初心不就是和一群有情有义的人做一件有意义的事情么!
开源贡献者心力建设的下一层,在我看来就是能做一个有温度的人。开源的世界需要更多的理想主义和利他主义,不能只有冰冷的代码片段构成,或者充斥着简单死板的唯规则论调。"Community over code" 是 Apache 社区的行事准则,社区的成功除了建立在代码之上,更加来源于社区的维护者的如何待人处事,是否能够做出合理的决策。
在我的程序员生涯里,有几位前辈对我的技术观和世界观产生了深远的影响,比如 Cassandra 的原作者 Avinash、Apache HBase 东八区的第一个 Committer 天梧,当然也包括了 Milvus 项目的发起人星爵。正是在这些前辈的悉心指点和栽培之下,我才能够不断熟悉开源技术、了解开源文化、在开源环境中成长,最终成为了一名开源项目的维护者。
一个问题对于维护者而言只是举手之劳,也许只是敲一个命令这么简单,对于一些社区用户来说却可能非常头疼,甚至会影响到他们的“工作饭碗”。因此我一直不停的修炼自己,希望能够对社区的用户和开发者足够友好,也许正是一点点善意的表示就能够改变一个人对开源项目的看法。
最后,心力的建设也往往来自于内心的矛盾。
众所周知,开源并非一种商业模式,纯粹的开源项目也无法给开源贡献者带来任何经济利益。在技术方面,开源是创造软件的最好方法,因为它可以加速产品的反馈和创新,而近年来开源软件的重新兴起则得益于“付费支持”:诸如 Open-core model 和 SaaS 等商业模式的成熟。大量成功的社区和软件背后往往都有着一家持续投入的商业公司。
对于像我一样在一家开源公司工作的贡献者而言,"You always wear two hats",简单来说,就是既需要关注社区的健康发展,维护社区用户和开发者的利益,又要保证公司提供的商业服务具备足够的价值并获取商业上的成功。这需要很好的平衡开源和商业之间的关系。但是这并不容易,开源公司做商业化经常会遭遇失败,并且因此折戟沉沙,比如这三类典型问题:
想要破局,需要企业决策者和开源维护者有大格局和平常心。
在我看来,开源软件必须对用户提供价值足够大的核心能力才能实现好的商业化,而非通过微创新提供一些小的用户价值就试图从中盈利。好的开源项目想要商业化必须能够形成飞轮效应、形成技术创新、形成社区规模,以及商业价值的良性循环。因此,心力的另一种修行在于足够的克制,既是对商业化节奏的克制,也是坚持项目核心价值而不过度拓展开源项目边界的克制。“Dream big,Step small”,我坚信在开源软件本身提供了对用户足够有价值的功能之后,自然会带来可以产生商业价值的其他企业级诉求,比如:可靠性、性能成本、工具插件、审计服务、安全、托管、数据交换等等。
总结
缺乏足够心力,就难以在繁杂的日常工作中守住本心和快乐;缺乏脑力,就会像没头的苍蝇到处乱撞拿不到结果;缺乏体力,会导致愿景大于执行,量变积累不足无法产生质变。
我十分荣幸能够加入到 Milvus 这样优秀的开源社区的建设工作中,让我在“体力”、“脑力”和“心力”上都有了一个全方位的提升。
参考文献
https://github.com/uber-go/guide
https://github.com/kubernetes/kubernetes
https://github.com/yanliang567
https://tisonkun.org/tags/%E5%BC%80%E6%BA%90/
https://book.douban.com/subject/35466335/
https://hueniversedotcom.wordpress.com/2016/01/26/how-to-use-open-source-and-shut-the-fuck-up-at-the-same-time/
作者介绍
栾小凡
Zilliz 合伙人兼技术总监
栾小凡是 Zilliz 合伙人和技术总监,同时是 LF AI & Data 基金会技术咨询委员会成员。在加入 Zilliz 前,他在阿里云担任研发经理,负责 NoSQL 数据库 Lindorm 的研发工作。此前,他曾先后在美国甲骨文公司和软件定义存储公司 Hedvig 担任软件工程师。栾小凡拥有康奈尔大学计算机工程硕士学位。
感谢你看到了这里,如果你厌倦了在大厂“拧螺丝”,和我们一样打心底认可开源的价值,信奉长期主义。欢迎加入 Milvus 社区以及社区背后的商业公司 Zilliz [https://zilliz.com],相信我们的职位列表中,一定会有适合你施展拳脚的机会。
期待擅长 AI、数据库、高性能计算方向的你、喜欢参与开源社区运营元气满满的你、细致耐心能够持续完善文档的你,和我们在开源路上一起前行,做全世界最好的向量数据库!
更多推荐
所有评论(0)