康威定律的边界 - Project (项目) 的设计脉络
前言
最近 Bytebase 在准备 Tutorial,过程中同事问到了 Project (项目) 的设计背景。看似习以为常的 Project 其实在设计过程中确实经历了反复的推敲,其设计也体现了 Bytebase 作为市面上唯一一款面向研发组织设计的协同产品,和其他同类产品从产品形态上本质的区别,所以也值得展开讲一下他设计背后的思考。
引入 Project 的初衷
在所有同类产品中,Bytebase 应该是唯一一个引入 Project 模型的产品。Bytebase 当前最核心的功能 是 schema 的变更流程,而要实现这个流程本身,光通过一个工单就可以了,这也是其他产品实现的方式,在 Bytebase 里,对应工单的模型也有,叫做 Issue (工作项)。那为什么还要额外引入 Project 这个模型呢?
先看我们官方文档上对于 Project 的概念介绍:
Project
is a logic unit to model a team effort. It's similar to the project concept in other dev tools such as Jira, GitLab.Project
is the container to group logically relatedDatabases
,Issues
andUsers
together. In Bytebase, ADatabase
or anIssue
always belongs to a singleProject
.Project
is also the peering entity with the VCS repository to set up version control workflow.
Project 对应的实体模型是 Team (团队),他作为一个容器把 Databases, Issues, Users 这些对象聚合在了一起,同时又能和诸如 GitLab 这样的 VCS 上的 Project 形成一一映射,如下图左上角所示:
我们先看传统的数据库运维平台,主要是针对 DBA 场景设计的,关注的是数据库集群的运维,而变更工单 / SQL 审核通常是一个子模块,下图是业内另一款广泛应用的开源产品 Archery 的主界面:
可以观察到 Archery 的工单会关联一个组,这个组就是用来映射一个研发团队的。这个组的功能是简单的标签 (组名称) + 几个 Webhook 的配置:
我们再看相对应的 Bytebase 主界面:
Bytebase 的工单概念 Issue 是关联到 Project 的,下图是 Project 详情页,可以看到一个 Project 下涵盖了很多信息和模块:
我们用 Project 对业务研发团队进行了建模,每一个团队创建对应自己业务的 Project 管理数据库,而不是混杂在一个全局的工单列表里。这个设计背后的思路则是来自康威定律的启发:
引入 Project 的目的是因为我们把 Bytebase 定位成一个研发组织里的团队协同工具,而不是一个简单的工单系统。后者主要给 DBA 使用,开发工程师只是上来提交工单走一个流程,用完即走,业务侧数据库的日常操作还是割裂在其他地方的。
而 Bytebase 通过 Project,研发团队能把数据库研发流程中的实体 Databases, Issues, Users 以及对应的代码仓库都串联在一起,这使得 Bytebase 不仅是 DBA 的阵地,同样也成为了研发团队的阵地,Project 就是阵地的边界,Project 之内属于研发团队,而 Project 之外属于 DBA 团队,而 DBA 和研发团队又同时驻留在 Bytebase 中,形成了协同的闭环。
为什么选择 Project (项目)
上一段介绍了引入的初衷,我们再看一下原始的需求,其实有两个:
对研发组织里的业务研发团队进行建模 需要一个容器,把管理数据库所涉及的实体聚合在一起
这个问题和起名有一定的关系,但也不全是。当初在做设计的时候,考虑过三个选项:
Application (应用) Team (团队) Project (项目)
Application 的出局
Application 通常是对于具体应用的建模,Application 可以对应一个单体应用 (比如手机上的 app),也可以对应一组由各种微服务组成的应用,具体的 Application 粒度取决于业务架构师的拆分。通常基础运维层的最佳实践是以应用为中心 (application-centric) 构建整个基础运维体系,自然 Application 是其中最核心的模型,比方说在 CMDB 中,串联起各种信息的就是 Application ID。
不过 Application 是第一个被排除的选项,原因是 Application 接近于对实体的抽象,从层次上来说和 Database 接近。而在 Bytebase 里,我们需要一个 Database 的容器,所以是需要一个在更高层的逻辑抽象。
Team 和 Project 之间的抉择
这两者之间的选择更加微妙。因为我们本身就是对于团队的建模,用 Team 也是顺利成章。比如在笔者欣赏的项管工具 linear.app 里,就是使用了 Team 模型,并且在 Team 之下有 Project 的概念,代表一个团队下面的项目。
权衡良久之后最终选择的还是 Project,最核心的因素还是因为在 Bytebase 要集成的生态里,占主导地位的产品如 GitLab, Octopus Deploy 都是采用了 Project 模型,尤其是 GitLab,是 Bytebase database-as-code 方案里的核心关联应用。所以为了靠近用户熟悉的概念,降低认知难度,最终选择了 Project。
Project 迭代至今的演化
Project 作为核心模型,自然是出现在了 Bytebase 最初的版本里,经过 1 年的迭代,Project 模型本身很稳定,只是在他之下新增了诸如 Backup, Webhook, Sheet, Event 这些关联对象,进一步增强了 Project 的能力。目前社区有呼声的是支持 Private (私密) 项目,实现本身的复杂度并不高,因为这只是一个属性,事实上我们在 schema 层也已经做好了准备,只是还没有在代码层实现。
总结
凡事无绝对,不过 “Project 将存续于 Bytebase” 的概率无限趋近于那个绝对。毕竟像 Project 这样的核心模型,一旦引入就很难去除,而一开始没有引入的话,后续要添加至少也是伤筋动骨了。
如果读者里有 AWS 用户的话,应该知道 AWS 的基础资源体系里是没有 Project 这个模型的,一开始所有的资源都在 Account (代表用户) 下,后来又引入了 Organization (组织) 来进行更好的管理。笔者相信 AWS 应该是考虑过引入 Project,只是在做调研时发现,复杂度已经大到无法做这个重构了。这也导致了 Project 这个概念不得不在 AWS 不同的服务中被重复实现,个人觉得这是 AWS 在顶层设计上不如 GCP 的一个地方 (当然 AWS 也有比 GCP 高明的点,之后另表了)。
笔者也思考过,当用户进入 Bytebase,初遇 Project 是怎样的感觉,尤其是对于那些之前用过类似产品的同学,会不会也产生困惑,明明是一个 schema 变更流程,直接提供一个工单提交就可以了,为什么上来要绕一下,先创建一个 Project 呢。就像当年笔者在 GCP, 也读到过从 AWS 迁移过来的用户吐槽,说干嘛非要人家先创建一个 Project 才能创建真正要用的 VM, 数据库这些资源呢。
Project 作为一层额外的抽象,使得业务研发团队在 Bytebase 上拥有了一个独立空间,能够管理业务数据库的所有操作。
舍得舍得,有舍有得。我们说 Bytebase 是一款研发协同产品,这是一个简化的说法。毕竟单凭一个工单,DBA 和业务研发工程师也能进行协同。所以更确切的说,Bytebase 是一款面向整个研发组织设计的协同产品,通过一个个 Project 来有序地划分各个业务研发团队。在一个 Project 之内,业务研发团队则可以管理所有数据库相关操作。
一个稍具规模的研发团队中,会有 DBA,也会有多个业务研发团队。能让 DBA 有序地管理这些研发团队在数据库上的操作,能让研发团队和 DBA 在同一个平台上管理业务数据库的整个生命周期,能让数据库管理和代码管理串联起来,这都是 Project 带来的魔力。