阅读视图

发现新文章,点击刷新页面。

大厂开源之殇

本轮开源之风吹起迄今数年,最大的影响还是越来越多的商业公司开始探索开源方法能够如何改变自己的经营策略。

开源策略循序渐进分成使用、参与和发起。在发起开源项目实践一线的,一个是打着开源旗号的创业公司,另一个就是大型企业尤其互联网企业(大厂)。

前者我在过去的文章里已经详细讨论了他们的动机、面临的风险和应对策略。

本文将关注大厂发起的开源项目的共同特点,讨论围绕这样的开源项目聚拢起来的企业研发团队、市场运营团队、用户开发者之间常见的认知失配问题。值得说明的是,这些问题虽然是大厂开源常见的问题,却不是大厂开源独有的问题,对其他开源项目的建设也有参考意义。

用户不买账:我要怎么用起来?

首当其冲的问题,是大厂开源的软件,离开了内部需求和重度集成的基础平台之后,很难为其他用户场景产生价值。

通常,大厂开源的软件,来自于基础架构团队剥离其提供服务的核心,例如微服务中间件的核心框架、日志收集和分析系统、配置中心和监控系统等等。这些软件开发之初,是为了服务企业内部业务对基础软件的需求。

企业内部的需求是特定的,而且往往倾向于把业务的需求推到基础平台来解决,随着集成程度的增强,边际成本不断降低。例如,内部平台上有一个配置中心,其他所有的软件启动时都默认环境里有这样一个配置中心,从中取得对应的参数做初始化。例如,内部平台有一套监控系统,有一套日志上报和分析的流程,这些逻辑都很容易侵入到其他组件当中。

这就导致大厂一旦要开源,经常是一股脑的把整个基础平台都打包开源出来。BAT 开源的软件当中,被当做拳头产品的,很多是这类全家桶式套件开源。

  • 字节跳动的 CloudWeGo 是 Golang 和 Rust 的微服务中间件套件;
  • 阿里巴巴的 SOFAStack 是 Java 的微服务中间件套件;
  • 腾讯捐赠到 Linux Foundation 的 TARS 是 C++ 为主的微服务中间件套件;
  • 字节跳动的 KubeWharf 是云原生应用管理套件。

这些套件,往往你很难单独拿其中一个跑起来,而是需要把全家桶都部署起来才能用上其中任何一个功能。

这样,用户选择这个套件的时候,就需要每个被全家桶带进来的软件都能较好的解决其对应领域的问题,否则就是浪费,很难过内部审查这关。然而套件开发都是针对大厂内部的需求,对于外部用户的定制化需求很容易无法满足,而又因为高度集成实际就是耦合而不好扩展,最终在大厂之外难以被用户用起来。更有甚者,有些功能用户压根不需要,但是大厂内部的业务是需要的,大厂内部的基础平台的部署又是标准化的,用户时常会发现全家桶里有毫无价值但是又需要吃资源的组件。

此外,在软件诞生的企业里,部署运维这个全家桶套件的流程往往是经年累月磨合出来的,有很多的故事和康威定律的结果,这样的历史在其他任何用户那里都是不存在的。运维的难题是定制化以外的另一个阻止用户使用的重要原因。

那么,大厂开源之前,把软件之间的依赖解耦,做好封装和模块化,不可以吗?

这样做是很有难度的。ByConity 是字节跳动基于 ClickHouse 改出来的一个号称云原生数仓的软件。它的核心架构依赖 FoundationDB 和 HDFS 这两个服务,虽然这两个服务对应的软件是开源的,用户理论上可以自己起起来,但是纵览整个编译和部署的手册,我相信没有几个人能够真的跑起来。

可以想象,在字节跳动内部有一个云平台,直接提供了相应的服务和自动配置的深度集成逻辑。这样看来,ByConity 不仅是云原生的,几乎是火山引擎云原生的,离开了这个平台,该软件的使用成本急剧上升。这样开源出来的软件,用户自己都跑不起来,何谈后续的反馈和参与呢?

无独有偶,阿里巴巴开源的 PolarDB-X 也对如何跑起来只字不提。虽然我们知道它是一个 MySQL 的魔改版本,但是毕竟会为了这个软件而来的人,想知道的肯定是如何利用那些独特的功能。我看到 PolarDB-X 的 Wiki 页面讲了不少技术设计、理想和参数手册,但是到底怎么跑起来,还是不知道。可能这些功能在阿里云上对应的产品里已经被很好的集成并提供给客户,但是对于拿到这个开源版本的用户来说,他能使用这个软件为自己带来什么价值呢?

当然,大厂开源也有把开源软件自己的产品化做得好的。

例如阿里巴巴捐赠到 ASF 的 Dubbo 项目,就以其充分的组件化和插件化,得到了社群生态良好的集成。同样是微服务中间件,Dubbo 的核心足够小,而且没有对其他软件服务过硬的依赖,用户可以先跑起来解决一个特定的问题,再在使用过程里逐渐添加或自己开发集成做增强。最终,扩展和集成对接口的需求回流到上游,扩展和集成本身共享到社群,这样的正循环帮助 Dubbo 灵活地服务各种不同的微服务场景。

同样,腾讯开源的影响力标杆 ncnn 有一个完整的 HowTo 列表,告诉用户怎么在各种环境下跑起来,生成用户内容。通过用户内容的传播聚集人气,并在解决一个又一个用户问题的正循环里不断打磨软件的成熟度。

NCNN 的起步指南

ApolloKvrocks 是另外两个来自企业的有口皆碑的开源项目,前者孵化于携程,后者来自美图。它们后来都脱离了大厂的开源体系,独立运营,在面对真正的用户需求时较好地解决了问题,从而得到了用户的信赖,也就有了源头活水。

开发者晕头转向:我该如何参与?

大厂开源之初,经常会想象项目一呼百应,开发者蜂拥而至,社群生态一片繁荣的景象。然而,项目实际开源之后,真实情况常常是门可罗雀,只有公司员工在提交代码,甚至 commit 都是从内部同步出来的,堪称只读开源。

除了没有回答好软件对用户有什么价值,用户到底要怎么用起来的问题,导致从根本上失去源头活水以外,另一个可观的社群增长阻碍,是由于内外流程失配带来的开发者难以参与的问题。

我在《企业如何实践开源协同》当中提到的第一点就是需要建立内外共享的工作流。否则,如果在设计开源方案的时候,没有把共享工作流考虑在内,即使代码公开,大部分开发流程也会保持在企业内部。如果开发者不是企业员工,则根本无法参与。

在实际接触了许多企业开源项目的需求之后,我能理解企业内部总是需要一个响应客户问题和解决研发排期的流程,但是在这样的背景下,为了良好的社群协作,仍然需要一个完整的、同企业内部流程啮合的开源工作流。

这里的核心原则是对社群参与设置的检查点,开发者需要有能力做自我检查。典型的场景是开发者提交一个补丁以后,在合并之前需要走哪些步骤,他心里应该是有数的。

腾讯开源的数据处理方案 InLong 项目,在 Apache 的流程模板加持下,从合作开发到软件发布,都是有迹可循的。其官网上仔细地记录了如何参与和如何发布的文档。进一步地,腾讯内部的数据处理系统也跟随开源版本发布,仅在内部对紧急问题做 hotfix 处理,所有的信息尽可能脱敏公开到社群,公共的改动会 upstream first 的推到上游分支。

谷歌开源在相当一段时间里都饱受恶名,因为它们几乎没有响应过任何外部参与者提交的补丁。不过,我在 Protobuf 的参与体验却不算差。Protobuf 的 CI 流程虽然依赖于内部系统,但是其结果会报告到 GitHub Pull Request 的 Check Status 上,所以开发者至少可以知道自己是否通过了测试。同时,Protobuf 的 CI 日志是可以公开访问的,我在贡献 Ruby 模块的时候,就通过自己读测试日志排查问题,数次避免了需要等待内部员工告诉我哪里出错了。

许多运行不良的大厂开源项目,往往是完全不考虑外部参与者的旅程体验,只是简单地维持先前内部研发的流程能工作即可。

TiDB 项目虽然不是大厂开源,但是从来自大厂的工程效能团队接手项目基础设施之后,整体的考虑方式也出现了相应的症状。

例如,在 PR-39440 里,他们试图在 TestCase 里加上某个测试必须对应某个内部系统 ID 的做法。这对于外部参与者来说完全是不可理解的,也不知道在自己正常改代码加测试,到底要怎么跟一个自己看也看不见,整个流程都与自己无关的内部系统关联上。通常,如果工程效能团队想要掌握一些指标,是可以在开源的工作流之上,通过分析测试的报告,提供内部的关联信息元数据,从而以对外界透明的方式来完成相同的需求。然而,对于设计工作流之初就没有考虑过开源协同的人来说,假设所有人都是我的同事,大家都工作在同一个上下文,才是熟悉的味道。

其他许多大厂开源项目甚至没有可以当做例子的内容,因为其开发过程完全和开源协同不沾边,也不在任何一个开放的代码协作平台上进行,你只能看到有 commit 神秘地被同步出来,没有任何解释,自然也无从参与。

上面说的是工作流上的问题,我在《共同创造价值》里提过,开发者参与协同的两大问题,除了知悉工作流解决怎么做的问题,还有可以做什么的问题。

大厂开源很多时候还是按照原先的产品计划和研发流程来进行,从未想过社群可以如何参与,自己又可以如何借助社群的力量提升软件的质量和增长软件的生态。

虽然开源之初,大厂的决策者就预想了开发者蜂拥而至的场景,但是要么根本没有想过这些人为何而来,如何引导他们参与,要么干脆假设这就是一批不用发薪水的员工,应当服从公司安排,接受任务指派,按时按量按质完成工作。

显然,社群成员不是你的免费员工,他们为开源软件和社群努力,而不是为公司努力。

为了正确引导外部开发者的参与力量,ClickHouse每年都会发布自己的 RoadMap 计划,大致告诉开发者今年要做什么。每当有一个新的想法和设计,也会尽可能地分享到社群,打开沟通的渠道。虽然大多数时候,功能还是由当初的 Yandex 或现在的 ClickHouse.com 的员工完成,但是一个打开的窗口允许参与者留言评论和理解整个需求的来龙去脉。

一般来说,社群成员是不能代替你完成软件产品的功能设计的,企业开源的项目仍然是企业项目,企业里的团队需要把控项目前进的方向。因此,企业视角里社群成员真正能够规模化地产生价值的地方,是功能初步交付后在各种使用场景的打磨,以及软件易用性和准确性的改进。

让你的社群成员知道你完成了什么功能,预期是什么样的,有助于激励他们试用起来。试用的过程会发现很多问题,引导和鼓励他们解决这些问题,是开启社群参与飞轮的第一步。

如果开发者来到你的社群,发现既不知道能做什么,尝试提交一些简单的改动,也完全搞不明白整个开发的流程,以及对 PR 被 Review 和被合并没有任何预期,那么开发者是不会对社群产生任何信赖感,也就不会留在社群的。

过度营销:KPI 导向的恶果

最后一个水面上的问题,也是无须多加分析就已经被广泛认知的问题,就是开源项目时 KPI 导向的过度营销,反过来妨碍了最初的影响力目标。

第一种过度营销,是夸大软件产品的价值。这一点我们在前面谈到“用户不买账”的问题时已经提到过,软件很可能没有解决什么普遍的用户问题,重度依赖大厂内部的业务假设和基础平台,用户用不上。这种情况下鼓吹开源软件如何解决大厂内部的问题,并自大地认为我能“降维打击”其他所有业务,最终用户用不起来,自然对你嗤之以鼻。

第二种过度营销,是为了人气指标提出一些零门槛的打卡任务,这一点其实跟“开发者晕头转向”紧密相关。由于工作流不透明,产品发展方向仅内部可见,不满足“共同创造价值”的前提条件,整个社群参与度非常低,堪称门可罗雀。这个时候,为了解决开源之初定下的 star 数和参与者人数的指标,运营团队乃至研发团队一起推出改拼写、改 linter 报错、改空白符等等零门槛活动,还发小礼品和大肆宣传,让真正想投入的开发者耻与之为伍,起到了反向的宣传作用。

第三种过度营销,是形式主义地搞出各种流程和机构。这其实是一种船货崇拜,即类似 Apache 和 Kubernetes 这样成功的项目,都搞了项目管理委员会、技术治理委员会、社区大使等等机构和角色,我们抄一套,是不是也就成功了?

很显然,在前面两个问题没有回答之前,软件的价值和整体的参与路径不清晰,搞出这些机构来往往是项目团队的角色扮演游戏和自我感动。漩涡在 BeyondStorage: why we fail 中对 BeyondStorage 社群为用户提供价值之前就沉迷于设计各种流程和机构做了深刻的反省。从用户和开发者视角来看,这个软件产品啥价值还没证明呢,就“封”了一群委员、委员长、秘书长、主席,到底是一个开源软件社群,生产软件我们好用起来和做反馈,还是一个官僚主义严重的团伙,主要职责是开会和弄文件的?

开发者关系:一种解决方案

上面介绍了大厂开源常见的三类问题,如果仔细看,会发现它们都跟软件产品研发团队相关。用户场景的问题需要产品定义,开发流程需要跟内部研发流程协同,市场营销的问题,也需要结合开发者的特点做相应的调整。

直接的结论可能是增加研发团队的职能,但是先驱者踩出来的实践可能是在企业当中设置一个开发者关系团队。对于有许多开源或待开源项目需要协调的大厂来说,还需要一个开源办公室来处理安全、合规和治理问题。

《开发者关系:方法与实践》介绍了一种开发者关系团队在企业当中充当开发者和产品研发部门信息枢纽的模式图:

开发者关系团队的定位

开发者关系团队了解开发者的特点,掌握社群当中开发者关注的内容,通过向产品研发部门提供开发者反馈,共同制作出开发者友好的 RoadMap 和使用说明。StreamNative 的开发者关系团队和研发团队紧密合作,推动 Apache Pulsar 网站 Getting Started 章节和 Landing Page 的改造,使得用户更好的了解 Pulsar 如何解决他们的问题,以及如何快速的在自己的环境上启动和试用 Pulsar 系统。

开发者关系团队熟悉开发者工作的方式,关注和协调社群当中的开发活动,通过不断改进工作流和促进消息流通,提升社群飞轮产生价值的速度和质量。在我开始处理 Pulsar 社群的开发者输入以后,Pulsar 主仓库的 Open Issue 和 PR 数量分别减少了 1000+ 个和 200+ 个。Issue 首次响应时间预期收敛到一周以内,大量的使用型问题在正确流转到对应核心研发之后迅速得到解答,许多明显易用性的问题补丁能够更快得到合并,而不是因为“不够重要”而被长期搁置。

开发者关系团队是不同于市场运营团队的内容出口,后者面向的群体是潜在客户(2B)或大众(2C),开发者关系的内容面向对象是开发者(2D)。开发者有其独特的内容喜好,开发者关系团队通过发布场景应用指南、软件使用教程、样例程序、线下会议和 workshop 等形式接触开发者,在开发者心智中建立起务实有效的技术品牌。

企业开源的软件协议模型实践

我在《企业开源该选什么软件许可证?》一文当中,已经从软件许可证的角度讨论过不同协议对企业开源的意义。

不过,那篇文章主要是从许可证内容出发的,即先给定了协议,分析完协议细节,再判断是否符合企业和计划公开的软件的情形。本文从企业开源的不同诉求和风险出发,结合现存的企业组织实践,重新讨论源码公开第一步就要面临的选择软件协议问题应该如何决策。

完全开放源码

完全开放源码,即以符合开源定义的软件协议发布企业自研软件的情形。

在讨论什么样的企业针对什么样的软件会采用完全开放源码的策略之前,我们先讨论完全开放源码的策略会给企业带来什么风险。符合开源定义的软件协议既包括宽容软件协议,也包括 Copyleft 式的协议,这里不做区分,因为企业面临的是相同的问题。

当然,对于企业完全自有产权的情形,企业随时可以改变软件协议以规避下面提到的风险。所以这里提到的风险主要涉及的是将自研软件捐赠给第三方如开源基金会,或者试图坚持完全开放源码策略的企业。

风险:竞争对手的商业竞争

我在《黑客与顾客:开源软件能商业化吗?》一文里讨论过,开源软件的用户包括黑客和顾客两种类型。

对于完全开放源码的创始团队来说,黑客用户既然自己有能力把软件用起来,甚至修改软件以解决自己的需求,那么可以认为开发成本已经付出,不从这类用户身上赚钱,而是寻求合作共建,是合理的。目前绝大部分“开源商业化”企业的逻辑,也是以服务无力或不愿承担开发和维护任务的顾客为主。

这一点,从目前新兴的 Elastic License 2.0 (ELv2) 和 Business Source License 1.1 (BSLv1) 的不少实践都允许在不进行同类商业服务竞争的情形下自由使用可见一斑。而上述两个源码公开的商业软件协议,想要避免的也正是同行黑客的商业竞争。

例如,业内提供 Apache Kafka 托管服务的企业数不胜数。在聚拢了相当数量的核心开发者的 Confluent 之外,UpstashAiven 这样的 SaaS 企业都提供了 Kafka 托管服务,更不用说大大小小的平台云厂商顺手提供的 Kafka 服务,例如 AWS 的 MSK 服务、阿里云的 Kafka 服务和红帽的 OpenShift Streams for Apache Kafka 服务等等。

这样的竞争使得 Confluent 不得不在简单的提供 Kafka 服务以外寻求新的增长点,例如只在商业版本提供多租户功能,以及在流计算集成上多次失败的尝试。当然,Kafka 的创始工作和捐赠都是在 LinkedIn 公司的主导下完成的。这样 Confluent 公司虽然无法效仿 MongoDB 公司在竞争对手直接提供商业服务的时候变更协议釜底抽薪,但是心里也不至于太不平衡。

ElasticSearch 和 MongoDB 起初分别以 Apache License 2.0 (ALv2) 和 GNU Affero General Public License 3.0 (AGPLv3) 发布,但是在 AWS 等商业公司低技术成本、高平台优势的竞争下,既无法找到新的增重点缓解危机,又无法抗拒近在咫尺的釜底抽薪方案,于是变更协议直接禁止使用源码进行商业竞争。

风险:团队分裂并参与竞争

Confluent 的案例里暗含了另一种完全开放源码的风险,即在软件可以自由演绎和商用的情况下,企业当中的开发者可能分裂出去单独进行商业运作并参与竞争。

Confluent 的创始团队来自 LinkedIn 公司,LinkedIn 本身没有提供云服务的业务,这种竞争尚不明显。其他处于 LinkedIn 情境的公司,甚至可以通过提供早期投资的方式,换取新团队比此前直接雇佣更低成本的支持。

Apache Hadoop 的故事演示了多家势均力敌的企业,同时基于非自有产权的开源软件做简单封装的商业化模式的风险。

在 Hadoop 的孵化公司雅虎不下场的情况下,Cloudera 公司、Hortonworks 公司和 MapR 公司为了竞争 Hadoop 私有化部署和运维服务打得头破血流,最后的结局是 Hortonworks 和 MapR 被收购,Cloudera 私有化退市。而退市以后的 Cloudera 公司,还是面临市面上拿着 Apache Ambari 封装或者自研大数据套件的提供商的剧烈竞争。

Apache Flink 的故事演示了在一家企业主导社群发展的情形下,部分团队寻求独立带来的分裂风险。

起初,Flink 在一所德国大学里开发并捐赠到 Apache 软件基金会。随后创始成员成立了 Ververica 公司,并于 2019 年被阿里巴巴收购。完成收购的阿里巴巴基本形成了对 Flink 社群的主导,并于接下来的一段时间无需顾虑其他基于 Flink 的商业服务的竞争。然而,就在过去的一两年里,核心团队分几次出走,加入到其他基于 Flink 做商业服务的公司,或者单独成立商业公司提供 Flink 服务。其中,走后面一条路的 Immerok 公司在不久前被 Confluent 收购,一下子使得阿里巴巴的流计算业务受到 Confluent 流存储 + 流计算的强势狙击。

在这些戏剧化的商业操作背后,Flink 本身是一个完全开放源码的软件,允许任何人和组织自由演绎和使用,也包括商用和提供商业竞争,是合规层面的一个基础性的支撑。

上面提到的例子里,即使有企业完成对社群话语权主导的案例,但是都全都是企业对开源软件没有自主产权的情形。接下来的这个例子虽然也是 Apache 软件基金会的项目,但是其中使用的方法是可以套用到企业自有产权的软件的。

这个案例就是 Apache Doris 项目。

Apache Doris 由百度的研发团队开发并捐赠给 Apache 软件基金会。凭借其符合国内企业需要的数据分析能力的设计,Doris 在一开始的十年里逐渐发展出一个可观的用户群体,其中相当部分还是有购买商业服务的潜在顾客。百度自己基于 Doris 发布了 Palo 数据分析产品,但是不久以后,部分核心开发者出走,并 fork Doris 发布了后来改名为 StarRocks 的同类竞争产品。没过几年,另一个研发团队出走并成立了 SelectDB 基于 Doris 提供同类的数据分析服务。

单看这个围绕 Doris 的竞争,似乎和 Hadoop 几家公司的竞争也没有什么差别。但是 StarRocks 并不是一个典型的围绕上游的版本,而是从某个版本硬分支的全新版本,目前和 Doris 的关系算得上是“大路朝天,各走一边”。这样硬分支的手段带来的竞争,即使上游是完全自有产权的软件,也无法通过修改协议来避免。

为了表明 Doris 的案例并非孤例,我这里再举几个类似的商业相关的硬分支案例:

  • Trino 是基于 Facebook Presto 的硬分支,后续 Trino 团队成立了 Starburst 公司提出数据网格(Data Mesh)概念做为商业化方向。
  • Lightbend 公司将 Akka 切换成年收入在一千万美元以上的公司使用就需要商用协议以后,Akka 社群的中立成员随即 fork 了 Akka 并在 Apache 软件基金会的孵化器中以 Pekko 的名字继续运行。
  • AWS 在 Elastic 公司将 ElasticSearch 切换到 ELv2 后,发起了 OpenSearch 项目并基于它提供了类似的商业服务。

面对上述风险,企业可以采取以下策略来降低或规避商业竞争的挑战。这些策略不是互斥的,应该根据企业自身的情况灵活组合使用。

策略:运维和高级功能

这是最基本的一个策略,即提供一个比开源版本功能更丰富的企业版本,包含闭源高级功能或运维支持,提供售后、服务水平保证和责任承担。

通常来说,它并不能在策略层面提供明显的竞争优势,因为你的竞争对手在能够自由使用相同软件的情形下,与你在这一层面的竞争是处于同一起跑线的。唯一的区别是你可能拥有更多熟悉软件的工程师,能够提供更好的服务支持。

但是,为了保持开源软件的活力、技术迭代与用户群,不至于变成开源一个闭源专有软件的快照,你的工程师会投入到开源上游核心的开发中去,这些成本由你支出,而你的竞争对手将无偿取得。同时,因此你的企业版本很难做出合适的代差以说服客户使用,而纯粹的运维支持,营收在竞争对手不需要维护一个内核研发团队的价格战下很难支持公司增长。

总的来说,这是一个保护性策略,即你必须要提供运维支持、售后、服务水平保证和责任承担,从而让客户能够像使用一个商业产品一样使用你提供的开源软件发行版或服务。但是它很少成为一个决定性的优胜策略。

策略:独特品牌建设

完全开放源码风险的共同点,是出现了其他企业或团队,以相同的软件代码基础展开商业竞争。企业开源的情形下,软件代码的归属是明确的,不仅创始工作在企业内的研发团队完成,版权所有的也是企业。这样,企业可以通过基于软件建设公司独特的品牌,将软件与公司品牌相关联来赢得在同类产品的用户群体中的心智竞争。

例如,Hashicorp 的基础软件均以 Mozilla Public License 2.0 (MPLv2) 发布。

实践上,MPLv2 可以被简单理解为允许包括提供同类服务的商业用途,可以和商业软件集成而不要求开放集成软件的源代码,可以基于已有接口的开发闭源的新机制实现,但是对软件接口的修改需要公开。MPLv2 许可的软件是完全开放源码的软件,一家公司直接拿走 Terraform 等软件,提供和 Hashicorp 相同接口的服务进行竞争是可能的。

然而,支撑用户采用 Terrafrom 等软件的,是 Hashicorp 对基础设施即代码的解释和实践。用户采购的不仅仅是 Terrafrom 或 Nomad 单独的一个工具,而是 Hashicorp 定义的一整套基础设施即代码的工作方式。如果下游企业仅仅是跟随这些概念,那么面对 Hashicorp 推出的新概念,自然很难第一时间跟进,更遑论超越。这样,用户就没有理由选择一个被上游带着跑的提供商,而是直接接触原创厂商。如果原创厂商的产品不能满足要求,也不太会选择追随者。

同样,商业智能数据分析服务的内核软件,例如 Cube.jsStreamlit 也是完全开放源码的。这类场景的定制化和依赖方法论的程度高,厂商基本可以将自己的技术品牌和开源软件相绑定,从而建立起竞争对手难以逾越的心智门槛。

Starburst 公司是另一个佼佼者,它拥有 Trino 即原先的 PrestoSQL 的版权,而 Trino 是联邦查询优秀的解决方案。Starburst 趁热打铁,推出了极具传播效果的 Data Mesh 概念,即不同来源和模式数据在同一个平台下进行分析,从而将数据打造成产品,而要做到这点,联邦查询引擎 Trino 自然能提供强力支持。这个概念的传播性之强,以至于 Confluent 也出书将自家的 Data in Motion 概念和 Data Mesh 捆绑营销,Trino 和 Starburst 借此水涨船高。

不过,对于标准化完成度高的赛道,这样的策略往往就难以提供竞争优势,而成为必须要做的保护型策略了。例如,MySQL AB 公司拥有 MySQL 的版权,但是在后来的发展里,业界对于数据库应该是什么样子的越来越有清晰的共识,甚至不少 MySQL 的运维专家自己都可以开设公司提供商业服务。MySQL AB 公司提供的附加价值有限,相当长时间内也不再提出具有开创性的品牌概念,终于在公有云服务登场以后,彻底被云厂商的关系数据库服务截取几乎所有利润。

策略:赛道维度升级

当完全开放源码的基础软件逐渐取得行业认可,甚至成为行业标准以后,品牌建设带来的心智门槛就会逐渐被抹平。这个时候,单纯提供简单的部署运维服务的商业模式,就会陷入到恐怖的价格战当中。在保持基础软件完全开放源码的前提下,要想另辟蹊径取得商业优势,就需要进行赛道维度升级,即基于开源软件提出新的解决方案。

要想走到这一步并不容易,如果初创企业辛苦研发后开源的核心软件,经过运营真的成为了某种标准,模仿者众,初创企业效仿 MongoDB 和 Elastic 直接切换成专有协议是目前仅有的实践。我们以一个无法切换协议的企业来模拟在这种情况下坚持完全开放源码、升级赛道维度将如何进行,它就是 Databricks 公司。

起初,Databricks 的商业模式还是 Spark 的简单包装。它和微软 Azure 达成合作,在 Azure 上捆绑销售 Apache Spark 性能优化的发行版

随后,Databricks 以 AI 为切入点,在 Spark 生态推出了 SparkR 和 PySpark 等集成支持,同时和 edX 合作推出了 Spark 系列课程,强化 Databricks 品牌在 Spark 生态中的地位。同时,在商业产品侧,针对 AI 的典型计算任务提供了标准化算力资源和一揽子解决方案,开始将 Spark 作为公司依赖的计算引擎核心而非差异化卖点。

再后来,Alluxio 和 JuiceFS 的探索让 Databricks 发现了 Spark 的计算能力加上存储以后的巨大需求市场,于是自研了 Delta Lake 软件,提出湖仓一体概念兜售新的解决方案。随着公司逐渐站稳脚跟,Databricks 也有了更多的资源投入到先前 AI 阵线上如今火起来的 AIOps 概念,以及完善整个湖仓一体故事所需的,包括 Delta Live Table 在内的一系列周边产品。

今天的 Databricks 已经不是一个简单的 Spark 提供商,而是一个 Data + AI 领域的企业级方案和云服务提供商。其他简单提供 Spark 作业调度和运维的企业,跟 Databricks 并不在同一个维度内竞争。

策略:市场占有率与开放标准

目前,能够在自有产权的情况下坚持完全开放源码,并在其他维度展开竞争的企业,其开放源码的软件都不是企业盈利的核心软件,而是打开市场和建立开放标准的敲门砖。换言之,企业对此类软件选择和坚持完全开放源码策略的一个主要原因,是企业希望完全开放源码的软件赢得广泛的市场占有率,甚至形成开放标准。

以开源的程序设计语言实现为例,在语言本身赢得用户之前,很少有企业能够直接通过售卖语言实现的编译器或解释器来盈利。瑞典电信公司 Ericsson 支持工程师 Joe Armstrong 开发 Erlang 语言之后,将整个 Erlang/OTP 平台完全开放。从当年的发布文稿中,我们可以看到开放标准的典型思路:

Erlang/OTP was invented within Ericsson and most Erlang/OTP users are still within Ericsson. In order to speed development of Erlang/OTP, ensure a good supply of Erlang/OTP fluent programmers, minimise maintenance and development costs for the language, and keep the OTP applications up to world class, we need to spread the technology outside of Ericsson.

也就是说,Ericsson 内部的电信系统高度依赖 Erlang/OTP 平台,为了保证劳动力市场上一直有人熟练掌握这一语言和开发平台,从而保证 Ericsson 内部系统不至于无人能够维护,Ericsson 希望完全开发源码,以期在公司以外的广阔生态中推广 Erlang/OTP 平台。事实证明,这一决定为 Erlang/OTP 平台起初在电信行业内的推广,以及后来在游戏行业中的广泛应用,再到近些年其底层虚拟机 BEAM 借助新语言 Elixir 的发展再次得到关注,都起到了至关重要的作用。Joe 为 Ericsson 创建高可用的服务打造了一个完整的开源软件和开发平台,但是如果没有开放源码,这将只是 Ericsson 这个如今已不那么有名的企业的一个内部系统。或许会成为一个仅存于谈话之中的传说,但是不可能有今天的生态。

同样是 Erlang 生态的一部分,José Valim 设计的 Elixir 语言及其开发的解释器和网站开发套件,代表了开放源码以赢得市场占有率的策略。

José 起初在自己参与联合创办的 Plataformatec 开发出了 Elixir 语言的解释器,以及 ecto 工具和 Phoenix 框架。后来,Elixir 的使用率日益增长,José 于是另外创办了 Dashbit 公司来提供 Elixir 应用的开发和运维支持。

从 Dashbit 公司的视角出发,其拥有部分 Elixir 核心生态软件的知识产权,但是它却没有通过限制核心软件使用,要求用户购买 LICENSE 的方式来盈利。这是因为,Elixir 毕竟还是一个小众的语言,用户使用量的增长才是做企业支持的基本盘。如果小有成就马上杀鸡取卵、竭泽而渔,那么新用户就很难有信心上车,而存量用户也会想办法跳车,最终生态凋敝,没人有理由购买 LICENSE 授权。

José 本人在 LinkedIn 上的头衔就是 Chief Adoption Officer 即首席(用户)采用官,可见 Dashbit 的开源策略当中对市场采用率的重视程度。同类的案例还有 VMWare 的 Greenplum Database、Spring Framwork 和 RabbitMQ 等项目,这些公司(在相关方向)的主要商业模式是提供支持和咨询,而不是售卖软件或提供云服务,因此其提供支持和咨询的对象的使用率越高越好。

再来看一种竞争型的开放标准策略,其中典型的当属 Google 的开源矩阵:

  1. Chromium 打下了浏览器内核的半壁江山。如今,多少网页应用都注明仅在 Chrome 上经过测试。
  2. Android 从 iOS 和 Symbian 的夹缝中取得了移动端市场的船票,并最终和 iOS 二分天下。
  3. Kubernetes 和 Istio 是 borg 技术溢出以后,Google 主动建立生态的尝试。在相当一段时间里,用上 Kuberneets 就“等于”云原生。

Google 是重度参与 C++ 标准讨论或者说竞争的,这可从 C++ 之父 Bjarne Stroustrup 的论文 Thriving in a Crowded and Changing World: C++ 2006–2020 中关于 C++ 标准委员会的讨论中窥见端倪。应该说,标准之争是激烈甚至残酷的。企业内部总有领先与行业标准所做的尝试,一旦行业后续面对相同问题时将另一种解法确定为标准,那么本公司不说此前的研发投入打了水瓢,至少也需要付出可观的额外努力来兼容新标准。Google 深知这点的厉害,而 Kuberneets 打赢容器战争,对比失败的 OpenStack、Docker Swarm 和 Apache Mesos 与重金投入它们的公司,Google 账面之外的获利不可计数。

无独有偶,Facebook 的 React 前端应用开发框架已经成为无可置疑的标准,对应 Google 推出的 Angular 势弱,多少投资 Angular 的企业和开发者损失惨重。

国内也不乏出于这个动机完全开放软件源码的企业。例如,Apache InLong 是腾讯大数据平台里数据集成能力的开放,Apache DubboNacos 是阿里巴巴微服务架设和治理经验的开源表现,CloudWeGo 是字节跳动中间件能力的系列开源行动,Go Kratos 是 Bilibili 开源的微服务框架。当然,这些软件集中在所谓的“中间件”领域,是另一个值得探讨分析的话题。

最后,上面提到的都是体量巨大或至少相对较大的公司,对于初创公司来说,有没有实践市场采用率和开放标准这一策略的空间呢?

肯定还是有的。例如,近期已被 Apache 孵化器接受的 OpenDAL 数据访问库,就是由 2021 年初创的企业 DatafuseLabs 捐赠的。又例如,CockroachDB 的存储引擎 Pebble 以 BSD-3-Clause 协议开源,连 PingCAP 的数据导入工具 Lightning 都在使用。

一般来说,初创公司更容易在细分领域或者新兴领域,通过开放源码软件来赢得大量声誉和共同维护生态成员都有需要的基础软件。

源码公开但禁止商业竞争

完全开发源码的策略会面临其他企业直接拿走软件代码,提供同类接口展开商业竞争的风险。即使是 Copyleft 式的协议,也很难逃过这样的竞争。

例如,红帽公司的 Red Hat Enterprise Linux (RHEL) 以 GPLv2 发布,这就使得 CentOS 可以利用相同的代码提供自己的发行版和服务。国内运维应该都了解,CentOS 在相当一段时间内是国内企业环境部署量最大的 Linux 发行版。这对红帽的商业模式造成了很大的冲击,最终红帽在 2014 年收购了 CentOS 公司。而 2021 年 CentOS 的作者再次复刻代码开发 Rocky Linux 进行商业竞争,或多或少再次冲击了 RHEL 的市场。

当然,今天的红帽已经不是单纯 RHEL 发行版的订阅提供商了,这样的冲击未必造成多大影响。然而,红帽面临这些问题毕竟是因为它是上游 Linux 的一个追随者,没有代码版权。对于新兴的初创公司来说,一旦通过开放源码的方式赢得了第一批客户,其他公司复刻代码直接竞争,一个行之有效的手段就是切换到禁止商业竞争的软件协议,杜绝此类事情发生。

然而,这毕竟是诱导转向的手段:切换软件协议后,企业与产品的品牌会收到打击,社群反噬和衰退引起用户客户逃离,生态集成出现问题不再繁荣。这些都是可能出现的问题。对于一开始就采取禁止商业竞争策略的企业,不会受到切换协议带来的打击,但是社群规模和生态集成的问题和进行切换的企业最终面临的状况是类似的。

接下来,我们讨论采用禁止商业竞争的源码公开协议的企业,如何构建其软件协议模型,面临哪些挑战并将如何应对。

核心禁止商业竞争

这一门派的著名选手是 MongoDB 公司和 Elastic 公司,分别创造了 Server Side Public License (SSPL) 和 Elastic License 2.0 (ELv2) 两个协议。

其中 SSPL 并不直接禁止商业竞争,而是要求在向企业之外提供同类服务时,必须将服务所有相关软件的源代码都以 SSPL 公开提供。由于这个条件对于服务所有相关软件的定义非常模糊,在没有判例的情况下没有公司想要测试到底它能不能“传染”到企业所有核心代码。目前,遵循 SSPL 开放服务软件栈的案例应该完全没有。

虽然所有软件源码公开、自由使用和修改是自由软件的追求,但是 SSPL 主要的目的是针对云厂商,限制它们的提供同类服务。因此自由软件阵营的 Fedora 社群明确否认 SSPL 是自由软件协议。同时,SSPL 的文本明确违反了开源定义第九条“不得限制其他软件”,因此也不被开放源码阵营所认可。实际上,它期望起到的作用就是禁止同类服务的商业竞争,虽然实际上由于协议条文的潜在风险,企业在不购买 MongoDB 的商业协议授权时,往往选择完全不使用 MongoDB 软件。

ELv2 对禁止商业竞争的意图和范围描述是清晰的,其文本量也相对较少:在允许用户使用、复制、修改和分发的前提下,不允许用户改变软件协议,不允许破解密钥保护的功能,禁止提供与软件功能相似的商业服务。因此,企业内部使用,以及把 Elastic Search 作为支撑业务逻辑的倒排索引系统是可以的,只要不直接提供跟 Elastic Search 相同或相似接口的服务即可。

另外一个常用的协议,Business Source License 1.1 (BSLv1) 则是由失败过一次的 MySQL 团队的部分成员重新创业的 MariaDB 公司创造的。它被用在 MariaDB 的企业级解决方案核心软件 MaxScale 上,其协议内容禁止用户使用 MaxScale 集成超过三个节点的集群,实际上就限制了有效的商业竞争,同时迫使大规模使用该软件的企业购买商业协议。

最后,介绍 Redis Labs 曾经为了禁止商业竞争,而在 BSD 3-Cluase License 上添加的 Common Clause 条款,它禁止取得软件源码的接收者“售卖”该软件。

Redis Labs 后来在社群大规模反弹下切换回了纯粹的 BSD 3-Cluase License 模型,而 Common Clause 也因为对“售卖”的定义及其模糊而几乎没有其他采用案例。自由软件基金会在对软件协议的评论里更是专门抨击了 Common Cluase 对 “Common” 和 “Sell” 两个词词义的污染,并强烈建议不要使用这个附加条款。

总的来说,使用范围较广的禁止商业竞争的源码公开协议只有 ELv2 和 BSLv1 这两者。我们看看其他公司的采用情况。

Airbyte 是 ELv2 + MIT 最典型的玩家。虽然它起初完全是用 MIT 许可发布的,但是很快就出现了模仿者打价格战。Airbyte 的主要研发投入仍然在其数据集成核心上,而这个需求相对来说是有行业共识的,在数据传输协议公开的前提下,打的就是集成多寡的体力仗。这种情况下,Airbyte 优化核心的投入会被下游无偿获取,其细分领域内建设独特品牌的策略提供不了公司想要的壁垒,而公司的人力又不足以完成升级赛道维度的开发。因此,Airbyte 选择切换核心软件协议,釜底抽薪。

由于 Airbyte 切换协议的时候,大型云厂商尚未关注到它,用户要么是自己部署,要么是使用 Airbyte 的服务,使用竞品服务的用户只是初现趋势,而 ELv2 本身并不禁止用户自己部署使用的情形,因此没有引起巨大的反弹。同时,Airbyte 的命令行工具、连接器代码和开发套件,以及数据传输协议实现仍然是 MIT 许可的,这就不影响社群开发的 Airbyte 集成继续以开源协议发布,对社群生态也没有造成明显的影响。当然,有人不喜欢这类变化,选择其他自由软件的情况是有的。核心模块的开发者规模虽然此前也主要是 Airbyte 员工响应,没有受到太大影响,但是也不会再有想象空间了。

BSLv1 在限制条款上留白,因此应该算是一个协议框架,实际使用 BSLv1 的企业分成两类。

第一类是 CockroachDBOutline 式的禁止提供同类服务,这在模式上和使用 ELv2 大体相同。

第二类会有各种更加严格的限制,不同于第一类只是禁止商业竞争,更像是确定了免费增值的策略,一旦超出“试用额度”,就需要付费。

祖师爷 MariaDB 的做法是限制以其 BSLv1 版本使用 MaxScale 的用户不得链接超过三个节点的集群。

Materialize 在禁止提供同类服务之上还要求只能部署单集群单并发。一般而言,有后面这个限制已经无法进行有效的商业竞争,不知道是不是担心注册多家公司进行公司级 sharding 钻空子。这样彻底抹杀可能性,可以说尽显商业专业协议的特色。

Lightbend 为 Akka 挑选的 BSLv1 版本,要求用户只能将 Akka 用于和 Play Framwork 下的应用进程通信。实际上,Play Framework 以 ALv2 许可发布,且强依赖 Akka 作为基础软件,这个条款更多是对 Play Framework 社群的妥协,保障 Play Framework 的用户不受 Akka 切换协议的影响,但是也不能从中暴露 Akka 接口脱离 Play Framework 使用。

BSLv1 相比 ELv2 还有一个特色,那就是它明确约定许可发布的软件在不超过四年的一个给定期限内,将自动视为以一个版权人挑选的 GPLv2 or later 兼容的协议许可发布。实践中,除了 MaxScale 选择在四年后以 GPLv2 or later 重新发布,其他企业均选择在四年后以 ALv2 重新发布。

对于行业来说,这在长时间轴上允许后来人自由使用这些代码,但是从商业竞争的角度来说,已经足够拉开和竞争对手的技术代差,劝退所有试图模仿的企业。

高级功能需要付费

另外一类包含禁止商业竞争的代码的软件协议模型,是限制高级功能的使用。

这一方案的代表企业是 GitLab 公司,其核心服务端软件代码协议模型有六个分点:

  1. 文档以 CC BY-SA 4.0 许可发布。
  2. ee 目录下的代码以商业协议发布,该协议允许测试和开发环境的自由修改和使用,但是生产环境使用必须有对应的订阅席位。
  3. jh 目录下的代码以商业协议发布,协议内容同上,除了企业主体变成极狐公司。
  4. 客户端 JavaScript 代码以 MIT Expat 许可发布。
  5. 第三方软件以其原协议发布。
  6. 其他代码以 MIT Expat 许可发布。

可以看到,代码在一起开发,但是高级功能需要付费才能商用。

这样的模式基本和完全开放核心源码,以闭源的插件或企业版代差来盈利类似,除了高级功能代码是公开可读的,而限制使用。

初创企业当中也有效仿这一模式的,例如 Bytebase 将高级功能以密钥上锁并禁止破解,Logto 将其云上部署的功能上锁。

总的来说,GitLab 能够成功应用这个模型,是因为它对企业需要什么样的代码托管平台,以及实施服务开发流程和研发效能等完整需求有一整套解决方案。当企业代码安全审计要求上去,或者实际发生过代码泄露问题,或者开发流水线严重拖慢了业务迭代,或者老板迫切想评估研发效能等等,这样的时候 GitLab 能够提供支持,并且其高级功能能打到痛点。至于国内学习这个模型的企业会如何发展,我们拭目以待。

企业实践开源的动机

随着开源软件全面占据软件供应链的各个阶段,商业公司开发基础软件或业务逻辑的时候,已经避不开对软件的使用了。经过一段时间对开源软件的使用,以及开源吞噬软件的趋势影响,研发能力突出的公司或团队,也会加入到开发开源软件的行列中来。

商业模型当中开源软件位置的不同,体现出企业实践开源动机的不同,并且会很大程度影响企业实践开源的行为。本文将讨论不同商业模型下,企业实践开源的动机和行为的差异。

商业模型是销售开源软件

第一类商业模型是直接销售开源软件。这种类型的企业以 MongoDB Inc.Elastic 为代表,是在 2010 年以后逐渐兴起的企业类型。

不过,说它们是“销售开源软件”也不准确。虽然在早期它们的商业产品是直接提供当时还是开源软件的 MongoDBElasticSearch 本身,但是随后由于源代码免费可得,包括 AWS 在内的云厂商直接利用免费的源代码在平台上提供同类的服务,这样的新形势使得这两家公司前后把软件协议改成 Server Side Public License (SSPLv1)Elastic License (ELv2) 来对抗商业竞争。

其中 ELv2 是明确的专有软件协议,禁止其他人提供同类的服务,也不允许破解付费密钥锁定的高级功能。SSPLv1 是对 GPL 系列许可的发展,但是要求与 MongoDB 一同构成服务的所有软件都需要按照 SSPLv1 协议发布,即包括开放源代码,这一点超出了 OSI 推出的开源定义第九条“协议不应该限制其他软件”的原则。实际执行过程中值得注意的是,MongoDB Inc. 采用 SSPLv1 的动机是对抗商业竞争,它同时鼓励用户购买企业提供的以专有软件协议发布的 MongoDB 以避免 SSPLv1 的要求。这种行为的动机与自由软件基金会制造的软件纯粹是为了让所有人能够自由地使用高质量的软件的初衷非常不同。因此,我并不将这样重新许可后的软件认为是开源软件,而是源码公开的专有软件。关于不同开源协议的讨论,我在《选择开源许可证》一文里有详细地展开。

无独有偶,曾经试图通过销售开源软件的公司,最终都走上了重新许可成源码公开的专有软件的路。

另一方面,越来越多的技术创业公司难以抵挡“开放源代码”的潮流和用户与开发者心理预期的转变,又清晰地理解了自己的商业模式就是销售将要开放源代码的这个软件本身,因此它们一开始就选择了源码公开的专有软件协议来禁止其他厂商直接利用公开的源代码销售同类服务开展竞争。

这种商业模式,本质上是 MongoDB Inc. 前任 CEO 所宣称的“免费增值”策略,即在不产生商业竞争的情况下,或者说对于用户,可以免费地使用该软件。等到用户深度参与之后,产生运维支持的需求,或者定制开发尤其是商业软件集成的需求,再转向唯一的供应商 MongoDB Inc. 付费获得支持。

我认为这种模式是说得通的,是一个好的市场营销手段。但是它与自由软件运动和开源运动的理念都是相违背的。

自由软件运动的理念是所有软件都应该能够被所有人自由地用于所有用途,显然用于提供托管服务就是其中一种用途,而上述软件协议不允许任何形式地提供同类托管服务。另一方面,自由软件运动的起源之一是 Richard Stallman 在打印机软件出现故障时无法取得源代码修复并重新编译和使用的痛苦。ElasticSearch 以付费密钥锁定的功能,是不是用户也需要的功能呢?如果我开发了同样的功能并且发布了,这里是否会产生破解的嫌疑呢?

开源定义(OSD)下的开源运动也包括了不限制用途和不限制其他软件的要求。进一步的,以 Apache 软件基金会为代表的开源世界,努力生产开源软件的基础是为了让所有潜在的参与者和用户平等地使用开源软件和参与开发。上述源码公开的专有软件,几乎只有相应商业公司的成员才能开发核心代码,并且解决的需求也是其客户提交的需求,随后进行商业交付。如前所述,如果有一个开发者完成了商业公司提供的付费功能并且期望合并到上游发布,上游会接受吗?

不过,抛开以专有协议许可的核心部分不谈,这些企业共同选择了在生态连接所需要的接口和模块方面,采用宽容的开源协议例如 Apache 2.0 或者 MIT 来许可。尤其是 Airbyte 提出的核心以 ELv2 许可的软件及其相应协议的模型,对于 CLI 和 Connector 等部分,都是开源软件。

Airbyte 的软件协议模型

如果把源码公开的专有协议部分视作商业软件而非传统意义上的开源软件,那么这种形式与接下来要讨论的依托于开源软件的商业模型就有很大的相似性了。只不过,当下的市场没能很好地区分开开源软件和源码可得的专有软件。如果一个企业的商业模型就是销售“开源”软件本身的功能,例如前面提到的 MongoDB Inc. 和 Elastic 还有 CockroachLabs 这样的,那么他们的核心功能转向专有软件只不过是时间问题,或者说只要面临商业竞争,就是经不起挑战的。

对于这样的企业来说,它的核心软件只能依靠自己开发,是不可能大范围地借助开源协同的力量完善和覆盖尽可能多的场景的。而且由于商业上的排他性,其他得到资本支持的研发团队也很难直接参与到开发中来。这样的软件与过去的专有软件,都会在开源吞噬软件的浪潮下最终被取代。关于开源吞噬软件在工程上的论证,《大教堂与集市》一书当中的 2.12 节《管理与马奇诺防线》有详细地论证。

这类商业模型的企业制造的软件生态当中可能出现的协同,也局限于用户在没有其他开源软件选择的时候,根据自己的需要和上游以开源软件开发的组件的情况,相应的做一些补充。例如 Airbyte 支持其他数据源的导入,例如 GitHub 其实是个专有软件,但是在 toolkitactions runner 以及 gh cli 等方面公开了相应的开源组件,这些组件也能得到开源社群的助力。

商业模型依托于开源软件

第二类商业模型是依托于开源软件构建商业产品。其实,在开源软件占据软件供应链各个环节的背景下,任何商业模型的依赖路径上存在计算机软件的,基本都会部分依赖于开源软件。当然,我们这里主要讨论的情形,是依赖深度较短的订阅咨询和解决方案的模型。这两者不是互斥的,往往一个企业会同时发展这两方面的商业产品和技术支持。

侧重订阅咨询的商业公司里,有名的包括红帽、收购红帽的 IBM 和收购了 Pivotal 的 VMware Tanzu 实验室。

这三家公司都是 Kubernetes 的重要参与者,提供类似于 Kubernetes 发行版的云平台 PaaS 订阅服务。红帽还以提供 Linux 发行版和技术支持闻名,VMware 则有 Spring 这个 Java 生态的杀手级开发框架背书。在 IBM 的开源软件技术支持列表里,涵盖了从应用开发栈、数据平台、云平台到 DevSecOps 等领域的一系列知名开源软件。

开源软件的源代码是公开且免费可得的,任何用户都能够自由编译、演绎和使用在任何场景下。但是,经过几十年软件行业的发展,以及社会生活数字化的浪潮,现在广泛被使用的开源软件已经复杂到没有经过专门的训练和经验积累,很难应对形形色色的业务需求。21 世纪最难得的真的是人才,上面提到的这些企业通过建立起开源社群当中属于自己的品牌,以及提供良好的工作环境吸引到高水平的软件开发人员,从而能够提供这些广泛存在于其他商业公司软件供应链上的核心开源软件的支持和订阅服务。

例如,红帽工程师耗费两年的时间打造了 Vert.x 反应式应用开发框架,并捐赠到 Eclipse 软件基金会共同创造出一个新的应用开发生态。厚积薄发,经过两年的设计开发和红帽客户资源增益的打磨,一个全新的开源软件和基于这个开源软件提供技术支持和订阅服务的商业模型正式成功上线。又例如,Pivotal 早在 2003 年就开始基于 PostgreSQL 开发 Greenplum 大规模并行处理系统,这个系统在经受 Impala 和 ClickHouse 等等后起之秀在十年之后的挑战之前一直代表相关领域的先进生产力。IBM 和 VMware 则是以收购见长,将这些已经成功走出订阅咨询路线的商业公司并入自己的企业服务版图,从而提供像上面 IBM 的开源技术支持那样全方位的服务。

阿里云、腾讯云和 AWS 等云厂商在其公有云平台上提供的开源软件托管服务,则是介于订阅和解决方案之间的商业模型。它们既有利用自己公有云平台和机器资源的优势,提供分毫未改的与开源软件相同的 API 的托管服务,例如 RDS 和 Redis 服务,也有发挥基础软件团队研发能力进行二次开发,产品能力升级或场景化定制的商业软件,例如 Ververica Platform 和 Tair 等等。

当然,售卖开源软件托管服务不是大型云厂商一家的专利。UpstashDatastax 都捕捉到了关系型数据库以外,数据平台对 NoSQL 数据库在 KV 类型和消息系统类型的需求,分别基于 Redis + Apache Kafka 和 Apache Cassandra + Apache Pulsar 搭建了自己的托管服务。由于依赖的软件属于 Apache 软件基金会或其他第三方组织,即使这些企业接近于直接销售开源软件,但是也无法重新以专有协议许可,因此这些企业被迫会转向上面提到的订阅模型,或者这两家企业选择提供上述开源软件全球可用和高效治理的服务,以此来产生自己的附加值。

这种附加值可以认为是一个企业级的解决方案,选择了 Upstash 的 Redis 服务,就可以获得在欧洲、北美、南美和东南亚都符合当地合规要求的开箱即用的 Redis 接口。另一方面,可以认为是企业基于自己对企业软件生态的理解,提供的一套方法论。例如上一段提到这两家公司是组合了 KV + Messaging 的接口提供服务,认为这两者合作就能解决业务在边缘场景下的数据存储和上报消费的需求。

基于 Trino 分布式 SQL 查询引擎的公司 Starbrust Data, Inc. 全力推广 Data Mesh 的概念,基于 Apache ShardingSphere 的公司 SphereEx 则全力推广 Database Plus 和 Database Mesh 的概念。这都是商业公司以开源软件为核心,打造出的一套有商业差异化的企业软件生态最佳实践或者叫方法论。只要你信了这套方法论,以同样的架构,同样的开源软件为核心搭建企业的软件生态,那么进一步产生付费,支持这一生态的顺利和高效运转,就是顺理成章的了。

彻底以产品化的解决方案来封装开源软件提供商业价值的模式,典型的企业包括 DatabricksTetrate 以及 Firebolt 等等。

说起 Databricks 这家公司,很容易想到的是他们的早期核心团队制造的 Apache Spark 开源软件。不过,Spark 早在核心团队还在大学实验室的时候就捐赠给了 Apache 软件基金会,因此同样改变软件协议来排他的销售软件是行不通的。Databricks 首先提供了具有明显性能优势的 Databricks Runtimes 产品,为对性能有极致追求的客户提供一个商业选择。然而,这样的用户毕竟是少的。于是 Databricks 开始了场景化的尝试,包括面向机器学习场景的 MLlib 和一系列的商业产品,包括面向一站式数据处理的 Delta Live Table 等组件,以及类似于上面提到的 Data Mesh 这样方法论的 LakeHouse 方法论与它的 DeltaLake 核心软件。

今天打开 Databricks 的官网,可以看到它早已在 Apache Spark 的基础上,长出了丰富的面向不同领域场景,面向不同用户案例和面向不同客户画像提供的一系列丰富的解决方案。构成这些解决方案的基础是 Apache Spark 丰富的生态,以及与开源的 DeltaLake 一脉相承的数据湖系统。在 Apache Spark 的名义下,在捐赠给 Linux Foundation 的 DeltaLake 的名义下,在 Databricks 官方 GitHub 组织的名义下,有着上百个连接数据平台开源共同体的开源软件。Databricks 在此之上又开发了面向不同场景不同解决方案需求的专有软件和商用代码,从而支撑起了自己的商业模型。

同样的,Tetrate 旨在提供云原生应用的网络治理方案。Tetrate 重度参与了 Istio 和 Envoy 以及 Apache SkyWalking 等开源项目的开发,雇员当中不乏相应社群的维护者乃至创始人。然而这家公司从未以相关开源社群所谓“背后的商业公司”自居,而是清晰地认识到自己的商业模式是依托于这些开源软件,提供自己定位在云原生应用的网络治理方案上所需的专有软件和企业级解决方案。Tetrate 有自己的 Istio 发行版,以在上游激进的发布模型之外为商业用户提供稳定、经过测试、高度兼容且 Tetrate 提供技术支持的 Istio 版本。此外,Tetrate 提供了 Tetrate Service Bridge 一揽子解决方案,在 Service Mesh 的方法论体系下支持客户将应用部署起来并完整监控和高效治理。

上面两个例子当中,Databricks 的工程师还有相当部分投入到 Apache Spark 和 DeltaLake 以及其他公司发布的开源软件的开发迭代,Tetrate 更是鼓励乃至促使重度参与提到的三个开源社群当中。Firebolt 的例子会有所不同,它很大程度上是作为 ClickHouse 的下游存在,极少参与上游开发。

Firebolt 仅将 ClickHouse 作为自己的计算执行引擎,在这一选型之外,完全专有化的实现了前台管控、集群管理和元数据管理、查询优化、数据索引和面向云存储的访问层。这样的商业模型也是依托于开源软件的,但是其依赖深度已经处于临界值。例如某些完全闭源的 Java 开发的专有软件,其中的网络模块也有可能使用开源软件 Netty 来实现,但是这种情形下,恐怕就不是我们这里所想讨论的企业实践开源的商业模式了。

Query Engine 起初完全就是 ClickHouse

Firebolt 这样的选型也算是自然的。如果你回顾 Databricks 的发展历程,它实际上可以被认为是选择了 Apache Spark 作为自己的计算执行引擎,逐渐发展出场景化的解决方案和 LakeHouse 一站式数据处理平台。不过,Databricks 的方向是逐渐走向开源。利用自己的先发优势,赚到行业内唯一提供商的收益以后,逐渐将自己的能力开源出来,以形成强凝聚力和活力的生态。这在下一节“开源标准以保护现有软件”会展开讨论。

反过来看 Firebolt 的做法,ClickHouse 在 fork 以后已经经历过闭源魔改,我相信时至今日它还是不是 ClickHouse 已经不好说了。Firebolt 也没有任何参与开源社群的征兆。因此我认为它会成为一个传统的商业软件公司,并在数据处理领域的开源浪潮下被吞噬。或许另一个世界当中的 Firebolt 走的是积极与上游协同的路线,共同发展 ClickHouse 的计算模块,并且在逐渐扩大自己商业版图的过程中把访问云存储的技术开源,查询优化和集群管理也开源,成为另一个行业标准的制定者。

回顾上一节当中我提到如果把源码公开的专有软件这一部分就明确认知成专有软件,上一节当中提到的商业公司也有形如 Databricks 和 Firebolt 这样不同的倾向性。虽然我相信开源运动持续下去,开源理念深入人心,因为高校研究突破也好,因为面向消费者的企业开源基础架构组件也好,因为下一节中要讨论的保护现有软件因此开源抢占标准也好,目前存在的所有专有软件,都会被开源软件所替代。

但是到那个时候,又会有新的商业需求产生,这些需求被开源运动的创造力满足的时间差,是存在提供解决方案的窗口的。世界之大,无奇不有,各种定制化的需求可以是非常特殊或小众的,而开源软件往往只解决主要问题和部分场景。另一方面,数字化进程大跨步前进,哪怕开源软件理论上能够解决好一个问题,但是实际实施的时候,仍然需要专家技术支持,并且维护后续迭代当中可能出现的问题。订阅咨询和解决方案这样依托于开源软件的商业模式,是能够长期存在的。

开源标准以保护现存业务

这种动机只有当企业成长到一定规模的时候才会产生,到这个时候,企业的商业模型往往已经非常复杂,甚至并不只是依靠软件服务来盈利。这种情形可以认为是上一节“商业模型依托于开源软件”的变体,即企业软件生态当中错综复杂地依赖了一系列开源软件,继而主要出于保护现存业务,顺带扩大技术影响力,来以开源软件协议公开企业内部的关键软件,以夺取开源世界对应业务领域的标准。

出于这一动机实践开源的典型企业就是谷歌。无论是 Kubernetes 还是 Istio 的开源,谷歌从中获得的直接商业利润都是不足以促成它做这样的动作的。然而,谷歌通过对自己内部业务应用的分析,看出容器技术和云原生应用是未来业务发展的方向。为了保护公司内部所有基于 Kubernetes 同类云平台的业务能够持续得到新生代工程师的认同和维护,谷歌需要占领云原生标准的话语权。

这里有段逸闻想必同行也耳熟能详,说当初谷歌找上 Docker 希望合作开发容器调度平台,但是 Docker 认为自己单独开发 Docker Swarm 也能赢下容器战争。结局大家也都知道了,Kubernetes 赢下了容器战争,Docker Swarm / Apache Mesos / Open Stack / Cloud Foundry 等等当初的对手则黯然退场乃至彻底死亡。

相关技术被潮流所抛弃对采用这些技术的企业和团队带来的打击是非常严重的。不仅仅是押宝相应技术的团队被市场所否定,就业前景黯淡,对于公司来说,这意味着可能几十万行、上百万行乃至更多的业务代码都成了技术债务。站在今天的角度能够看到的例子,就是欧美国家银行当中海量的 COBOL 语言写成的业务系统,如今能找到的有维护能力的工程师最年轻的也有六十岁以上。如果这个世界上能够维护这些系统的工程师已经绝迹,那么企业的业务就暴露在巨大的风险之下。显然,当初选择了 Docker Swarm 和 Apache Mesos 的企业也将面临越来越招不到人维护的处境。在这种情况下,唯一能做的就是及时将遗留系统迁移到上游标准,但是这样的工作往往需要更加精通被淘汰的技术的工程师才能牵头完成,并且相应的时间精力成本不可估量。如果迁移这么简单,那些 COBOL 代码又是怎么历经几十年都无人能够“迁移”的呢?

不仅仅是容器战争这样出圈的开源标准之争,Yahoo! 开源 Apache ZooKeeper 和 Apache Pulsar 等软件,阿里开源 Apache RocketMQ 和全面投入 Apache Flink 的开发,Netflix 开源 Apache Curator 和 Apache Iceberg 以及 Uber 开源 Apache Hudi 等等,都有保护自己线上业务的动机在里面。当然,如果能够借此机会树立公司的技术品牌,吸纳高水平的技术人才,乃至主导行业未来的发展方向,那就是意外之喜了。

不完全是软件行业为了保护现存业务,在开源技术以争夺行业标准的方向上,还有三个值得一提的案例。

第一个是启发我从这个方向看待企业实践开源的动机的例子。Bjarne Stroustrup 在 2020 年总结 C++ 发展历程的论文 Thriving in a Crowded and Changing World: C++ 2006–2020 当中提到了 C++ 标准委员会当中有许多耳熟能详的大公司的参与,包括苹果、谷歌、英特尔、微软、摩根士丹利、英伟达、高通、红帽和 IBM 等等。每个提案提出的时候,往往代表了某个公司或科研机构经年的努力、实践和生产检验。论文当中回顾了若干提案导致不同硬件厂商的标准之争、大学科研机构的方向之争和软件公司保护现存业务不受完全不同的标准的影响的争论。

例如,各家都有自己的协程实现和用例,如果标准库的实现与自家实现的关键设计和接口不同,那么就意味着以上游的分叉,这将导致上面提到的实现被开源社群所抛弃或者巨大的迁移成本的问题。对于硬件厂商来说,类似于 C/C++ 这样的系统编程语言是硬件接口接入软件层面第一个要打交道的层次。如果在并发语义、时钟接口或者硬件访问标准上采取了一家硬件厂商的方案,那么其他硬件厂商的众多生产流水线就面临立即被市场淘汰的风险,以及成为相应细分领域追随者而不是领导者或公平竞争者的劣势。

第二个是谷歌开源 Android 操作系统的例子。开发和开源 Android 操作系统之前,谷歌内部并没有大量的现存业务。但是众所周知,为了避免移动互联网时代的基础设施移动设备的操作系统被 iOS 全面统治,从而在谷歌和苹果的全面软件技术竞争上处于劣势,后发的谷歌选择开源的方式来开发自己的移动设备操作系统。谷歌在浏览器市场上也采用了类似的模式,谷歌浏览器的内核是开源的 Chromium 项目,这一选择或许受到了世纪初 Firefox 在与 IE 的竞争下赢得巨大成功的启示。不可否认的是,开源的 Android 操作系统形成的庞大生态,开源的 Chromium 内核衍生的一系列浏览器软件,成为了谷歌在这两个方向上核心技术极深的护城河,同时也极大地扩张了这两个领域的市场规模。

第三个例子是跨领域的特斯拉的例子。特斯拉进军新能源汽车领域时,这个领域的市场规模还很有限。即使特斯拉是行业当中无可争议的老大,新能源汽车在行业成熟度,全球化分工的可行性和社会认可度都是极其有限的。通过开源核心基础技术,不追究使用基础专利侵权,使得全球所有看到机会的人才投入到这个行业当中来。行业成熟度决定特斯拉能够持续地招聘到什么水平的人才。如果市场上只有特斯拉一家公司,那么选择这个方向的人心里就要打鼓,现在即使投身这个行业进不去特斯拉,或者特斯拉出现问题要调整或者裁员,也能找到其他岗位继续自己的职业生涯。如此,加上行业热情高涨,社会认可度高,人才投入到这一领域的概率和比例就大大增加了。另一个方面,社会认可度还可以增加大众购买新能源汽车的动力和信心,全球化分工则使得特斯拉的生产制造流水线能够放置到人力成本最经济的国家或地区完成。

企业实践开源的其他收益

前面三段分类讨论了不同商业模型下的企业实践开源的动机和形式的不同,这一段从企业实践开源的收益的角度出发,讨论上面没有专门点出的动机。

内容生产的原材料

定位自己为技术公司的企业,需要解决的一个问题就是如何建立和持续强化技术品牌。技术品牌打造的一个关键支柱是技术内容运营,内容运营最大的挑战是没有内容。巧妇难为无米之炊,如果企业的技术人才、研发部门的日常工作当中没有生产出有利于打造品牌的技术内容原材料,期待运营部门自己凭空创造出内容是非常困难的。

企业以开源文化或者开源办公室为支点,系统地采集员工在上游开源社群或者企业开源的软件社群当中的活动,就能为内容生产提供优质的原材料。例如许多开源社群都会有自己的 Weekly 新闻,记录最近一周开发团队和周边生态发生的要闻,包括实现了什么新功能,修复了什么问题,有哪些新成员加入,软件生态有什么新组件或者老组件的重大变更,社交媒体上有什么与本社群相关的热点。企业鼓励员工积极参与上游开源社群,积极地以开源协同的方式运行企业开源的软件社群,在这个从业者都有旺盛的求知欲和参与热情的行业当中,不难积累出值得宣传的内容。

这些内容都是 WORKING IN PUBLIC 的行为,因此也就不存在是企业“内部”的动作,从而出现茫茫多内容审核的问题。此外,内容运营最能激发参与热情和建立技术品牌的点,在于其他人也能方便地加入进来,验证你发布的内容当中提到的事情是真的,参与到发布的招募事项里面来,亲力亲为与其他社群成员形成联系。

实践软件工程理论

要想从 Apache 软件基金会的孵化器中毕业,成为 Apache 顶级项目,需要在 Apache 成熟度模型的指导下实践一系列软件工程的理论。

对于其他开源社群的建设来说,要想发挥开源协同的最大价值,同样需要在这个远远超出一个公司员工总数量级的开放式环境当中高效地协同不同的参与者。从代码到文档,从开发到测试再到发布,从协议合规到软件安全,从技术社群到开源生态,每一个方面都是对一个新生的开源社群的考验。

尤其是国内短于软件工程理论的交流和实践的环境下,企业鼓励员工参与开源社群,将自己所依赖的不构成明显商业竞争优势的专有软件开源并尝试建设一个开源社群,是一个很好的与全球同行切磋“高质量软件应该怎么制造”的路线。企业需要懂得软件工程的员工来做好自己需要的业务软件和基础软件,而缺乏现成可参考的案例和可以试手的对象,不仅对于学生是个问题,对于不像谷歌那样有一套完整的软件工程体系和大量可供参考和参与的软件的公司的员工来说,也是个巨大的问题。

许多程序员不知道文档应该怎么写,许多程序员没见过复杂的并发问题,许多程序员不了解软件构建的过程,对软件整体的交付流水线知之甚少,更有许多程序员不知道如何与其他成员沟通协作、合作开发。对这些全局视角和具体细节把握的不足,软实力的缺失,就是程序员能力的短板,虽然不是每个人都要是全面的人才,但是这应该是每一个从业者追求的目标。这些问题,只要你深入参与到开源社群当中去,或者自己运行一个开源社群,其实就有机会积累到宝贵的经验。

至于前文已经提过的建立技术品牌以后,带来的招聘上和客户取信上的收益,赢得开源标准带来的一系列价值,这里就不再赘述。

总结

根据企业商业模式与开源软件之间的关系,其实践开源的动机与具体实施的行为会有不小的差别。

我认为,直接销售开源软件终将被证明是不可行的。基于开源软件,提供订阅服务或技术支持,构建企业级的解决方案,是能够长久存续的商业模式,也因此提供了企业长期实践开源的源动力。当企业逐渐发展以形成复杂的商业模式以后,开源就不仅仅是技术影响力或者协同开发这么纯粹了。主动参与自己所依赖的开源软件的上游社群,或者以各种方式支持上游社群的发展,争夺开源标准,保证自己的现存业务在激烈的市场和技术竞争下能够长期存在,直到领域的终局,也是这一阶段的企业需要考量的动机。

企业如何实践开源协同

随着开源概念的红火,越来越多的企业将内部项目公开托管到 GitHub 等平台,也有越来越多依托开源项目建立起来的企业。对于这些企业来说,它们的目标不只是开放项目源代码,更希望能够形成开源共同体,打造围绕项目的软件生态。

然而,其中大部分项目由于成员背景的单一性,最终都终结于仅源码可得的形态。对于这些新兴项目来说,初始成员从属于同一企业是既定事实。在这样的前提下,企业应该如何实践开源协同,形成开源共同体呢?

共享工作流

从开发者的角度出发,根本问题是要共享工作流。共享工作流,即项目开发的核心流程只有一套,所有 contributor 无论背景都基于这套核心流程工作。

对于企业内部项目开放源代码的情况,要做到这一点并不容易。项目往往在企业内部已经有一套成熟的工作流。如果在设计开源方案的时候,没有把共享工作流考虑在内,即使代码公开,大部分开发流程也会保持在企业内部。如果 contributor 不是企业员工,则根本无法参与。

Case Study: OceanBase

这个问题的典型案例是 OceanBase 项目。

OceanBase 项目的源代码托管在 GitHub 和 Gitee 两个平台上,同时接受问题报告和补丁提交。通常来说,一个项目只会有唯一的问题报告和补丁提交方式。例如,Linux 采用 Bugzilla 记录问题,邮件列表提交和评审补丁。GitHub 上有 Linux 的镜像,但是是只读的。其他的例子包括 GCC 和 PostgreSQL 等,都会有唯一的工作流,其他代码仓库只是镜像。OceanBase 两边都接受问题报告和补丁提交,反而是对两边的反馈都不重视。

可以猜测,它的核心流程既不是 GitHub 上的工作流,也不是 Gitee 上的,而是企业内部的工作流。这种情况下,能从开放可参与的平台上提交的大概率就只有简单的拼写错误或者代码重构补丁。因为即使是资深的开发者,缺少必要的信息和充分的讨论,也无法更进一步参与。实际情况也是如此,内部的活动别说讨论和设计文档,就连提交都不是实时同步的。此外,项目在两个平台上的活动,基本只有一名维护者出面在处理。

企业开放内部项目源代码,允许任何人学习和使用,是有社会价值的。但是内外两套工作流,甚至开放可参与的工作流只是个添头,那就不可能形成开源共同体。如果这就是预期的目标,那倒也没事。只是对于辛苦应付这些留下来的缺口进来的简单补丁的维护者来说,他是否会觉得这只是另一种值班呢?无论如何,工作流的统一都有助于减少损耗。不管是干脆只保留内部工作流,托管平台上的所有活动都没有回应保证,还是尝试融合到开放工作流,真正做到开源协同,都比牺牲一部分人,做一些创造出来的边缘工作要好。

Case Study: Apache InLong (incubating)

致力于融合到开放工作流的典型案例是 Apache InLong (incubating) 项目。这个项目是由腾讯捐赠给 Apache 软件基金会的数据流处理平台。

在项目开放初期,也存在只有内部工作流的情形。不过得益于主要维护者的软件工程经验,在明确项目要以开源协同的方式运作以后,经过对维护两套开发流程弊端的分析,得出了要融合工作流的结论。既然是开源协同,那么融合的工作流就是共享工作流了。

一段时间的改造后,原先内部工作流的核心流程被迁移到共享工作流当中,包括问题报告、补丁提交和版本发布。原先内部工作流服务于企业需求的部分则基于共享工作流构建。

企业内部仍然有用户问题报告,但是归结到项目本身缺陷的问题,会脱敏之后报告到 GitHub Issue 上。为了解决紧急问题,企业内部的 fork 版本仍然会打临时补丁快速上线,但是救火之后正式修复的补丁会以 contributing back 的形式提交到开源项目上。最后是版本发布。一开始,只有内部项目在发版。开放源代码之后,就有两个同类项目要分开发版。经过一系列的改进,主要是问题报告和补丁提交的及时同步,最终两个项目能够以较小的同步开销同时发版。换句话说,GitHub 上托管的版本,就是企业内部使用的版本。企业内部可能有一些临时补丁,但是并不构成一个差异化内部版本,并且这些补丁是积极地被推进 contributing back 上游的。

可以看到,确定开源协同开发项目的方向后,共享工作流不是形式主义,而是能切实提高软件工程效率和减少摩擦的方案。

对于企业本身依托开源项目建立的情况,要维持共享工作流也存在很多挑战。这些挑战大多出自一个原因,那就是最佳实践的匮乏导致节外生枝的私下讨论。

Case Study: TiDB

TiDB 的代码仓库中有专门存放设计文档的目录。理论上,新功能,行为变更,以及其他重要改动,都需要一个设计文档。

我们可以从设计文档的时间线看出这一工作流的变迁。

  • 2018 年下半年,共 17 份设计文档。
  • 2019 年全年,共 6 份设计文档。
  • 2020 年全年,共 13 份设计文档。
  • 2021 年至今,共 19 份设计文档。

从另一个维度看,2019 年 5 月到 10 月,2020 年 10 月到次年 2 月,一共将近一年的时间里,项目没有提出过任何设计文档。

那么,TiDB 项目在此期间是停止开发了吗?没有。它一直以每个工作日合并 10 个 PR 以上的开发速度在前进。在此期间关于功能设计的讨论,其实是转进了企业的即时通讯工具或内部文档当中了。我们可以看几个例子。

这几个功能并不是没有设计,而是只在小范围内通过中文文档做出设计,就开始实现。甚至在 Cardinality Estimation Enhancement 的例子当中,以为 contributor 想了解功能设计和背景,被 assignee 以时间紧迫为由回绝。虽然 assignee 承诺会在完成后进一步披露消息,但是却没了下文。

另一个例子是 pull request 上的检查项变更。不仅整个过程是在企业内部决策后直接在开源项目上上线,共同体内的其他成员一无所知,而且对于 bad case 的处理依赖于企业内部的群聊,让人摸不着头脑。

其实这些案例,我相信相关成员并不是刻意要伤害开源共同体。设计和开发的需求是天然存在的,持续集成的改动也不是不能做,但是实际推动落实的成员,缺乏开源共同体当中工作的经验,难以站在一家企业之上的视角,以合理的方式开展工作,才导致了这些实际伤害了开源共同体的做法。

我在这两个方向都做过一些改良的工作。对于设计文档,我发起了一个 Public Design 的讨论,并且推动了几个重大改动的公开设计。在此过程中和复数的开发者沟通了公开设计的技巧,以及在此前提下如何高效地推进重要改动的落实。实际上,公开设计并不会损失效率。因为并不是内部讨论完成后拿出来公示,而是从一开始就放在公开渠道讨论。既然是开源协同,补丁提交本身也是公开的,这些材料有什么好隐藏的呢?相反,因为得到了潜在的更多反馈,能够在设计等早期阶段避免缺陷,反而公开设计是更加高效的手段。

对于持续集成,企业内部把研发和工程效能分成两个竖井,又把开源共同体仅关联到研发的工作上去,是这个问题的根源。组织结构问题不好解,只能先改变工程效能团队的员工的认知。当他以开源共同体成员的身份变更项目基础设施的时候,也通过提交议题,达成共识后实施的工作流来推进。实际上,这样改变以后,关注到项目功能开发的成员与维护基础设施的成员更能坦诚的交换意见,避免意料之外的改变激发矛盾。

Case Study: Taichi

Taichi 是一个主要面向计算机图形学的并行编程框架,由胡渊鸣博士发明。去年,他作为联合创始人创立了太极图形公司来支持项目的发展。

项目早期基本是胡老师一个人的工作。开放源代码并有 contributor 加入后,画风是这样的。

这两个 pull request 的三位参与者,彼时分别在美国波士顿、日本东京和中国上海。当时也没有成立公司,更不谈有企业内部的即时通讯工具或文档空间。所以你可以看到所有必要的讨论都发生在 GitHub 平台上。

时间拉回到现在,部分项目的开发仍然是有迹可循的。比如有个置顶的 RoadMap 作为当前正在投入的工作的地图,比如 Taichi 编译器前端类型检查有个 tracking issue 来记录工作。

不过,也会出现我在昨天看到的无描述 4000 行改动无评论合并的案例。

经过社交媒体的传播,目前这个 pull request 更新了部分描述。其实是一个学术研究相关的功能,在发出论文后希望 contributing back 到上游。由于变更较为复杂,早期设计出于研究原因不便公开,加上持续集成流水线的效率问题,所以采用了一步到位的合并方案。代码 review 私下发生在提交之前。

那么,这些信息昨天凌晨看到的我能够知道吗?答案是不能。

其实这种提交一个大改动的案例并不少见。Apache Flink 项目曾经多次发生过这样的事情,包括 2014 年 7 月合并 streaming 的原型,2019 年合并阿里巴巴内部版本 BLINK 等等。项目接受来自企业或学术团体的 contribution 是很正常的,其他开源项目也有研究室基于项目做出优化策略后 contributing back 的案例。

开源共同体接受 contribution 的标准做法仍然是公开讨论。只需要说明这件事情,解答潜在的疑问之后决定接受或拒绝 contribution 即可。如果 ti.Mesh 的研究结果是以这样的形式合并到代码仓库的,我想在一开始我就不会有疑惑和疑惑导致的误会。另一方面,公开讨论和 contribute 对开源项目也是一种保护。Apache 项目在接收重要 contribution 时都会考虑引入一个知识产权清理流程,确保接收 contribution 不会引入知识产权相关的争端。

Taichi 项目当中缺乏背景信息的还有这些例子。

当然,必须说明的是 Taichi 项目的大部分 pull request 是有背景信息的。上面这些案例的参与者,我想也不是刻意隐藏信息,而是成立公司之后,自然地在线下或者内部平台讨论。既然已经通过私下讨论得出结论,再刻意搬到 GitHub 上反而就是低效的。对于具备项目假设 contributor 应该有的知识就能理解的补丁,也不需要做作的讨论。

要想避免因为已经私下讨论得出结论,从而把共同工作流的一部分切换成内部工作流的情况,应该从两个方面入手。

第一个是在确定开源协同开发项目的方向后,所有技术讨论都以 GitHub 平台的内容为唯一信源。私下讨论是无法禁止的,只能从技术领袖开始以身作则,推动公开讨论。其实对于大部分企业员工来说,在哪讨论并不重要。真正让他们转向私下讨论的原因,是在 GitHub 上的评论得不到回复,而钉一下或者内部文档 at 有奇效。值得一提的是,Taichi 也有我曾经到的 TiDB 的问题,那就是没有一个活跃的开放式讨论渠道,即没有邮件列表的替代品。有个 Discourse 论坛,但是是面向中文用户而不是全球开发者的。开通了 GitHub Discussion 功能,但是只有唯一一个版本发布的公告。

第二个是作为共同体的领袖,应当积极寻找不同背景的参与者。如果已经形成了私下讨论的习惯,仅仅要求员工改变习惯是很难有效的。因为公开讨论的主要原因,是为了和企业以外的 contributor 交流,以获得有意义的输入和提高生产力。如果员工发现换个地方发言,得到的回应还是同事的回应,并且 GitHub 上的评论还是得不到即时的回复,这件事就推不下去。

前面的例子提到过,当 Taichi 的主要开发者天各一方,没有成立公司之前,这种沟通是自然而然的。实际上,Linux 和 Apache Httpd 也是这样的。除了邮件列表,Linus 很难找到另一个渠道收获他所需要的反馈。Apache Httpd 的早期成员一开始就是在邮件列表上沟通的。只有实际存在组织以外的高水平参与者,开源协同的最佳实践才有意义。对于企业员工来说,也才有直接合理的理由不在内部讨论。毕竟就某个特定的问题,他更希望听一听那个不同背景的共同体成员的意见。

招募新成员

寻找不同背景的参与者,其实就是作为共同体的领袖为共同体招募新成员。这是企业实践开源协同的另一个难题。除了为企业招募以外,应该如何为共同体招募呢?

End user

第一个要讨论的是用户。不过,用户是开源协同之外的内容。商业产品同样需要自己的用户。大部分用户也不会关心软件是如何实现的。

所以,要讨论用户,其实是要驳斥一些错误的观念。用户能够为你提供使用反馈,能够通过付费或捐赠支持项目开发人员持续投入,但是期待从用户群体中大规模地发现核心 contributor 则是不切实际的。

我听到过很多项目领袖跟我说,他的项目是独特的,因为不像大数据项目那样,用户本身也是开发者。它可能是一个数据库。哎呀,用户都是 DBA 或者数据分析师,根本不知道数据库怎么实现的嘛。它可能是一个机器学习框架。哎呀,用户都只会操作 Python 接口,根本搞不来核心 C++ 代码。

那我就想问了,你咋不去找那些就做数据库的人,就搞机器学习框架的人呢?你给团队招聘的时候知道找这些人,怎么到了给共同体招募新成员,眼里就只看到用户了。

其实我也可以理解。因为开源协同不够普及,大部分人提到 open-source 这个概念,第一印象还是一个市场营销的手段。或者提到“运营开源社区”,就把用户社区那些已有经验都搬过来。在这样的认识下 open-source community 就是开源社区,而不是开源共同体。其中“我们”是唯一的开发者,是懂行的。其他人是只会小修小补的爱好者,或者干脆啥也不懂的用户。

这个误区有点像思维定式。你现在要找的是有能力开发项目的参与者,那就去对应的群体里找就可以了。

当然,如果你就想做用户社区,就没打算搞开源协同,也是一种选择。对于这类需求,我建议研究 MongoDB 的做法。它们搞得挺好,这里就不展开了。

Ecosystem

抛开用户不谈,开源共同体当中的 contributor 还可以进一步细分。其中有一类 contributor 关注生态互连,另一类关注项目的核心逻辑。

如果项目提供了足够多的扩展点,或者策略替换机制,那么关注生态互连的 contributor 就能够快速参与进来。

例如,Flink/Spark/Presto 等项目都设计了 connector 机制,连来连去就能创造出大量的工作。例如,几乎所有项目都可以搞多语言 SDK 玩玩。TiKV 就有不少于五种编程语言的客户端实现。例如,PostgreSQL 提供 FDW 机制,不仅支持连接外部数据源,更暴露了参与 planning 阶段的计算下推接口。例如,Linux 其实也有丰富的扩展机制,支持多种架构和驱动就是一个例子。

上面这些都是项目本身的机制,更广泛的生态还包括解决方案的整合。例如,从 Netty 的角度看,Flink 就是它的生态的一部分。从 Flink 的角度看,serverless 技术栈 StateFun 又是它的生态的一部分。经常听 database 的开发者说自己的软件直面终端用户,但是其实就互联网业务开发者来说,中间是隔了一层 ORM 框架的。哪怕是数据分析师,大概率也隔了一层可视化框架。另外,数据的同步和搬迁也是应用设计不可缺少的一部分,这就是各种中间件能发挥作用的地方了。

总之,这类 contributor 还可以再细分。一类是关注项目提供的机制替换实现的,大部分可以从有可能提供实现的项目开发者当中寻找。例如项目的部署机制希望支持 Kubernetes 环境,那找一个热衷于写 Kubernetes Operator 或者刚学会跃跃欲试的开发者参与,就很有可能产生正面效果。另一类是关注项目整合形成用户解决方案的。实际上,项目开发者最终基于项目实现盈利,往往就是以某种解决方案出现。只要你发挥想象力,生态整合的可能性就是个乘法,不愁找不到参与者。即使是核心逻辑被单一企业掌控的 MongoDB 项目,其生态也是非常繁荣的。

Kernel

当然,项目的核心逻辑也是非常重要的。如果项目本身不够坚挺,那么就不会有用户使用,也无法激起 contributor 连接生态的动力。

项目的核心逻辑是一个项目的主要价值。这些逻辑通常由项目的初始成员定义。在企业主导项目的情况下,这些初始成员往往背景单一。同时,出于传统组织观念的影响,初始成员往往以企业当中的项目团队作为自我认同,团队等同于项目,也因此将核心逻辑的开发层层“保护”在看不见的高墙之内。

以项目团队作为自我认同,无怪乎招募新成员的时候,自我认知自动翻译成团队招聘,而想不到还有其他可能性。

反观成功的开源项目,数据湖项目 Apache Hudi 由 Uber 捐赠给 Apache 软件基金会,在项目快速发展过程中吸引到了阿里巴巴和 T3 出行等企业的员工的参与,并吸纳了上述企业背景的开发者作为项目 PMC 成员。对于后续参与的企业的员工来说,他们在企业当中虽然也有项目团队,但是显然不会觉得项目归企业内的项目团队所有。对于 Uber 来说,来自其他企业的核心 contributor 的声音也不可忽视。这样,Apache Hudi 成功建立了一个开源共同体。

要想为项目招募开发核心逻辑的参与者,我觉得应该做到以下三点。

第一点是改变认知。上面已经介绍了错误认知的危害和避免错误认知的最终形态。我把这种正确的认知称为“开发者的两顶帽子”。同一个开发者,既是开源共同体的参与者,也是企业的员工。这两个身份虽然从属于同一个人,但是却有着不同的诉求。只有区分开这些不同的诉求,一部分是开源共同体的目标,一部分是企业基于开源项目创造商业价值的目标,才能避免认知混乱导致人为制造出参与的高墙。

第二点是公开讨论。前面讨论的很详细了,这里再补充一个点。当你真的身处一个开源共同体当中,不做公开讨论才是奇怪的。例如 Apache Hudi 的例子,如果 T3 出行的开发者想要实现某个功能,除了公开讨论寻求共识,别无他法。

公开讨论还有一个额外的好处,那就是方便引用。不少基于开源项目建立起来的企业,运营人员整天发愁哪里有技术内容可以发布,写技术文章好像变成了一个苦差事。其实技术话题公开讨论,天然的就有高质量的内容可以推送,其中悬而未决的议题,也是 contributor 参与的绝佳切入点。例如 Engula 项目在社交媒体的输出,基本就是设计文档或者开放式讨论里值得发布的内容。

最后一点是积极招募。前面分析 Taichi 的例子也提到过,认知改变的假设需要多样化的开源共同体成员来验证,保持公开讨论的做法也需要不同背景的 contributor 参与。除了公开讨论能够吸引到潜在的参与者,积极招募更意味着共同体的领袖要主动思考谁是你要找的人。

对于每个项目来说,这个问题的答案都不一样。但是认为这个问题没有答案,或者说人才都在企业当中了,则是一种傲慢。

同样举数据库的例子,哪怕你有 Oracle 那么大,世界上也还有相当一批人在开发 PostgreSQL 等项目。这些人并不是一辈子就做这一件事的。只要你的项目足够有趣,他们就有可能投入。

另一方面,泛泛而谈数据库这样一个复杂的领域其实是一种懒惰。既然复杂的项目本身会分模块开发,为什么在招募新成员的时候就只想着完全理解整个领域的人呢?如果项目的并发设计不佳,只要是精通该语言并发编程的专家,愿意 contribute 做改进,你管他懂不懂数据库的专业概念。醉心于编译器前端的开发者,也许能解决 SQL Parser 当中经年的性能问题。进入 Apache 孵化器的项目的导师,往往也不是项目所在领域的专家,甚至不是开发者,但是他们能够帮助项目以 Apache 的方式建立起开源共同体。

以这样的方式去寻找潜在的开发核心逻辑的成员,相信你的视野会更加广阔。

其实,这才是“开源共同体”的含义。不止于项目,也不是社区居委会,而是围绕开源项目的发展,基于对项目的认同,形成的多层次合作共同体。

❌