在公司最近关于mono repo和multi repo的讨论中,学习到了一些新知识,也触发了一些感想。mono repo 顾名思义,就是公司全部的源代码都在同一个代码库里。固然并不必定这么绝对,有的公司可能有若干个大的代码库,例如M公司的Windows, Office或F公司的前端和后端。multi repo则是指每一个项目,每一个服务都拥有本身单独的的代码库。html
当一个公司到达至关规模的的时候,公司最重要的资产--源代码随着体积的膨胀,会带来一系列的工程挑战:前端
同步,编译和构建时间可能变得没法忍受。编程
保证代码的稳定变的困难。开发人员同步代码后可能没法成功编译或运行后端
单一代码库包含不一样的编程语言。编译工具的不一样使得新建,更改构建过程变的很困难。缓存
让咱们先来看一下这个行星上最大的代码库——谷歌的代码库:Why Google Stores Billions of Lines of Code in a Single Repository架构
谷歌起始于perforce,后来迁移到自行研发的Piper和CitiC,
代码库包含3千五百万commits, 二十亿行代码,85TB的代码
两万五千工程师天天产生一万六千个commit,另外包括两万五千个自动化系统的commit编程语言
这是一个极端的例子,可是咱们能够看到,首先,85TB的代码远远超过一台开发机的硬盘,必需要支持可以只同步少部分代码并构建。同时还要保证全部的依赖关系必须可以同时处理。例如,更改一部分代码,全部依赖于它的模块必须也要可以正确编译构建。构建系统必须是分布的和高效的。分布式
每两秒一个commit,必需要保证commit的质量。谷歌付出了巨大的人力物力来维护这样一个单一代码库,到底是为了什么呢?原文的总结以下:
˲ 统一版本控制,代码拥有一个惟一真实的view;
˲ 更容易支持代码共享和重用;
˲ 简化依赖关系管理;
˲ 每个变化都是,原子的变化;
˲ 更容易的支持大型重构;
˲ 更容易的支持协做跨团队;
˲ 团队边界和代码全部权的转移变得更容易灵活。
˲ 代码结构更清晰,树结构提供隐含团队命名空间便于管理工具
这一切都很美好,但对于通常公司意味着须要付出巨大的投入。不少系统,好比分布式构建有着很大的技术挑战, 须要极强的依赖分析和缓存构建。学习
与mono repo对应的是,multirepo,也就是代码库是分散管理的,每一个项目,每一个服务拥有本身的代码库。这样项目组能够很快的推动,彼此之间的影响会很小。开源项目能够看做是这种方式。成名公司中,Amazon能够说是最成功的例子配合它们松耦合的SOA架构,也取得了巨大的成功。采用这种方式,最大的挑战是代码共享和依赖管理。因为每一个代码库自由选择本身所依赖的版本号,一旦试图共享代码,版本之间的冲突变的很难避免。好比 A 依赖于B,C, B,C都依赖于D,但它们依赖于不一样版本的D。这时的处理就变得很困难。固然咱们可使用开发工具去检查发现这种状况。但有时当必须须要B或C升级时,额外的沟通成本就不可避免。
如何选择,这是一个问题。在一家难以投入大量人力于构建系统的时候,可能multi repo 在短时间内更有助于生产力。但从长期来看,单一, 高效的构建系统和创建专业的团队支持系统是更好的选择。而今天,谷歌开源了Bazel,Twitter开源了Pants,Facebook开源了buck, 在必定程度上下降了门槛。