据Jessitron报道,几天前,在匈牙利首都布达佩斯,我和耶斯·哈姆博(Jez Humble)探讨过这样一个问题:对于团队来说,CAP定理同样适用吗?在分布式数据库系统中,CAP定理指的是Consistency(一致性)、 Availability(可用性)、Partition(分区),三者不可兼得。如果一定要在三者中选择2个,必须要有Partition。
比如在开发软件时,除非这个软件全部都是由1个人开发的,否则我们必须要选择Partition,因为我们无法将所有人的思想都融合起来。在数据库中,我们需要在Consistency (保持数据相同)与Availability(总能获取数据)之间做出选择。
而随着团队扩大,我们需要在Consensus (以同样的理由和方式做事)与实际完成工作之间做出选择。换句话说,我们需要在Moving Together与Moving Forward之间找到平衡。
1.Moving Together
第一组的研究毫无价值。尽管决策是一致的,所有工作也都在顺利进行,但输出非常有限。当有人生病时,所有工作都要停止。
第二到第七组的研究比较理想:团队成员通过积极沟通,交流想法,整体对话输出足以弥补互相交谈损耗的时间成本。对于团体中的每个人来说,建立彼此的“心智模型(mental model)”是非常可行的,他们可以了解其他人想要知道的东西。当每个利益相关者都是其他人的朋友时,很容易达成一致性。
当超过1个团队时,就需要对合作协调的成本进行权衡。以2到7人组成、需要密切合作的团队为例,可以用下面这种细高的空心箭头代表他们的输出潜力。
这个团队正开发可在古董店中运行的软件。看看他们的进展轨迹,完全是在向前移动。
接下来,在继续开发注册销售点(POS)工具时,我们添加更多内容到网站。我们分为两个团队。我们依然在开发同样的数据库项目,建立同样的品牌,为此我们需要密切协调。我们利用彼此的工具。尽管更多人意味着更多协调开销,但我们都喜欢彼此,为此这不会成为太大负担。毕竟,我们属于同一个社区。
到目前为止,古董店的运营良好。网站吸引了更多零售业务,临近的古董店也想要在我们的网站上为自己打广告,所有努力都取得了成功,我们增加了更多顾客。对于合作的团队来说,这意味着我们需要面向外部的报告,同时意味着我们需要数据管道。
图注:紫色箭头和蓝色箭头加入到红色和绿色箭头中。它们之间线路交错,就像混乱的网络。这些箭头一点点被填满,因为这些协调需要更高的成本。紫色箭头的联系更少,显得有点儿满了,但它可以指向左边30度角。
但是保证同样的共识和协调水平是不切实际的。协调成本会大幅增加,因为新人的加入不会像团队中的每个老人那样建立起彼此的心智模型。他们不知道其他人已经知道的东西,或其他人需要知道哪些信息。
如果合作伙伴团队接触数据库,它可能成为销售或网站的拐点,他们的协调能力将被削弱。每个人都需要检查每件事,这会大大拖慢整个团队的前进步伐。紫色团队在协调方面浪费的时间少些,为此数据渠道正被建立,但与绿色团队没有任何关系。在这个方向上,对于销售点来说没有任何意义。
这种规模上的混乱也会导致方向混乱,那么我们如何能扩大前进步伐呢?
2.Moving Forward
另一个极端是脱钩和设定边界。在数据管道、销售点以及网络之间设定明确的API。分离数据库,在必要时重复数据。各个团队都按照他们自己的时间表运行,缺少协调。这由更宽的箭头代表,因为向后兼容型和功能退化的代价都是非常昂贵的。
图注:这四个箭头中,每个都很宽很短。有几条线连接它们,它们已经被填满,但工作需要宽度(即巩固)而非高度(前进)。
这些团队越来越成为沟通负担日益沉重的团队。区别在于:团队规模确实扩大了。在协调再次受限前,我们可以添更多团队。
亚马逊就是这种模式中最具代表性的例子:向后兼容所有的东西。每个Moving Forward团队都“全副武装”,彼此完全分离,因此没有任何团队能够预测其他团队需要什么。这令AWS产品的诞生成为可能。可是,这需要大量技术开销,或许也不会塑造最好的文化。
谷歌采取了另一种极端做法。它们的独立大型仓库(也称为monorepo)允许团队之间更多联系。库可以共享,它们可用这些极端工具来弥补。测试、重构工具、自定义版本控制以及构建系统,甚至整个编程语言。数以千计的工程师在谷歌负责基础设施,以便于他们能够利用技术推动Move Together。
3.Balance
对于我们其他人来说,在拥有7到1000名工程师的公司中,我们负担不起这些极端措施。我们必须要问:共识的重要性在哪儿?共识正将我们推向何方?
在制定目标和方向方面,共识非常关键。我们正创建同样的企业,我们需要在相同的起跑线上取得领先。我们都需要达成一致:哪种方式更好?
在后端,共识几乎处于瘫痪状态。当我们需要任何协调时,当我在无法预测或不影响其他团队的情况下无法升级库时,当我的数据库改变可能打破一个比我的系统对生产更关键的系统时,这些都会导致我们都陷入瘫痪中。不要让任何团队分享数据库或库。
利用共享工具和专业技术会怎样?如果每个组运营自己的数据库,这些箭头会变得很宽很快速,除非他们在监控和冗余上敷衍了事——他们将抠门,系统将变得脆弱。我们不想在每个组改变所有事情。
答案是做一些宽的箭头,共享工具作为内部服务由各组与内部客户来维护是很好的。要使数据管道服务于这种合作伙伴关系和报告团队。要使数据团队向其他团队提供支持不错的数据库实例。(他们依然分开使用数据库,但现在我们有共享工具与他们合作,还有在他们中间同步数据的管道。)
(绿色、红色和蓝色箭头长而窄,多数忙于工作,它们之间有一些线相互连接,紫色和新的黑色箭头短而宽,也忙于工作,宽箭头(内部服务)在顶端与长箭头(产品组)连接)
重复使用只在有稳定可靠的API时、在没有进度表耦合时和提供组关注客户服务时才有帮助。
结论
避免共享代码库,除非你是谷歌,有覆盖任何地方的完美测试,或者你是亚马逊,有向后兼容支持这些代码库的整个团队。
鼓励共享想法。整个组织的人之间的随机通信有巨大潜力。了解其他组在做什么,这将改进你自己的方向和加快开发进度——只要你听到的都是信息而不是义务。
在我们想实现的目标、为什么这么做和如何(高水准)地实现上达成一致。指出同一方向,各自独立行动。
每个组织都是一个分布式系统,即使我们相互坐在一起也是如此。协调也可以联合行动,但不自由。随着你组织的发展,要有意识地权衡,因为一致变得不太有用而且代价高昂。要知道进入组织的新人会体验到比你更高的协调成本。让各组按照自己的道路前进,只要我们在同一方向共同前进就行。分布式系统是困难的,但我们能做到。