git push 如何处理积压?

3
我正在考虑设置分布式git服务器的部署。我知道这是git默认执行的操作,但在这种情况下,这些服务器将作为单一真相源,并提供集中支持的所有帮助。
目前,我们的代码库和使用服务器的开发人员数量很少(几百个),但一旦部署,我预计至少会有一千个用户采用并进行自动构建。当这种情况发生时,我预计推送到中央支持的git服务器的数量将增加多倍,这将导致向其他中央支持的git服务器推送增加。
为了限制由所有这些服务器互相推送更改引起的推送风暴的可能性,我打算采用标准的中心枢纽结构,其中一个或两个服务器将充当主服务器,接收来自辐射服务器的推送,并将这些更改推回到其他辐射器。
我的问题出现在我开始考虑全球定位的辐射服务器上推送的多次影响时。我已经在实验室中尝试模拟此情况,从我所看到的情况来看,推送过程只是等待前面的进程完成。在小型部署中,这很好地运作。然而,当你将构建自动化投入运作时,提交/推送活动可能会呈指数增长。如果我决定创建一个后接收挂钩,以处理这些推送的每个客户端推送基础,我可以预见到这些过程可能会在客户端服务器上积压,等待中心枢纽接收更改。
我的问题是:
我的担忧是否有效?这些进程是否会因等待sshd的时间间隔而失败,或者git本身是否有指定等待时间间隔的方法?
除了监视系统进程或包装推送命令以跟踪其完成时间之外,是否有一种检测此操作积压的方法,或者说,检测主服务器上的挂起接收状态?
还有人能向我指出一些与此主题有关的线程或文章吗?
最坏的情况是,在钩子式推送的地方使用定时间隔来推送每个存储库,但我希望保持事物的自由流动和快速,因此钩子式推送将更受欢迎。

我假设你提到sshd是因为你正在通过ssh进行推送? - Cascabel
是的,ssh用于推送/拉取/克隆操作。 - Jon Erickson
我觉得我已经回答了你的主要问题;特别是我解释了推送不等待前一个完成,这使得你的大部分问题都不相关。只有当你试图支持超过网络处理能力的推送时才会遇到问题,而这并不是一个真正的 Git 问题。如果需要,我会在我的答案中添加一点关于推送和获取操作大小的内容。但是网络容量规划并不是这个网站的主题 - 如果你有相关问题,请尝试 serverfault.com - Cascabel
1个回答

2
您是否真的希望推送一个如此高的卷,以至于可以使服务器遭受拒绝服务攻击?从您的问题中,我并不完全相信。
推送工作方式如下:
本地端与远程端交谈一段时间,足以确定需要传输哪些对象。
本地端将所有必要的对象打包成packfile。
本地端将packfile传输到远程端,在临时文件名下存储。
传输完成后,将packfile重命名为实际文件名。
仓库尝试根据请求更新引用(例如,将主分支指向新推送的提交)。
传输可以并行进行。因此,您真正需要担心的是是否有足够的网络容量来支持所有推送,而我怀疑这不是问题。推送和提取非常小。它们只传输必要的对象(没有在另一侧的对象),并且基于其他一侧已经具有的对象对内容进行增量压缩,因此大小与传输提交所代表的差异的大小成比例。如果您无法处理传输那么多数据,则我不确定任何分布式源代码控制系统是否适合您。
话虽如此,如果两个人设法同时推送到同一个分支,或者更有可能,如果一个人认为他们已经更新并可以推送,然后在他们成功推送之前,有人先推送,那么第一个开发人员必须在推送之前进行拉取。这些是非常真实的问题,但处理它们的方式不是通过分发您的存储库。而是采用完全避免该情况的工作流程。
首先,如果您确实正在查看一千个开发人员,他们可能不都在同一个存储库上工作,对吧?如果是这样...您可能希望将其拆分。如果需要以某个高级别联系在一起的事物,请查看子模块。例如,Linux内核源代码就是这样存储的。有很多位,每个位于自己的子模块中,然后成为父存储库的一部分。没有太多人需要操纵父存储库;他们只处理自己正在使用的子模块的存储库,而且没有太多人正在使用它。您真的不想处于代表10M行代码的单体存储库的情况下。
现在,如果拆分后,您想进一步减少许多人尝试推送到一个分支的问题,您可能只想停止那种情况。让集成器(或几个)将其推送到主要分支,并让其他所有人将其推送到自己的分支,集成器可以合并这些分支。这有许多变化,但您明白了。

最后,如果可能的话,请尽量避免使用集线器/分支模式。大型开源项目可以成功地从单个存储库托管,因此似乎这对您也适用。请记住,大多数操作都是增量式的(推送/获取),而不是完全克隆,因此它们不会传输大量数据。如果带宽是一个问题,您可以通过正确分割存储库来减少要传输的数据量。


我的问题基于过去使用SVN和ClearCase的经验。为了回答你的一些问题,开发将广泛分布在多个存储库中,因此不太可能有大量实际开发人员访问一个存储库。更有可能的是,我过去看到的是X组为多个组件和子组件执行自动构建。这些构建会在检测到本地工作副本/存储库中的更改时触发,并且可以按顺序或同时触发。创建一个模拟负载,比实际用户数高得多。 - Jon Erickson
磁盘存储为SAN。网络背板为10 GB。当然,标准警告适用-并非所有网络带宽都可用,可用的WAN带宽可能要少得多,并且SAN并不专门用于Git,因此您每天/每小时的使用情况会有所不同。我需要确保Git在利用这些资源时是一个体贴的邻居。 - Jon Erickson
从管理员的角度来看,从单个存储库进行托管是理想的,我同意。然而,对于国际用户来说,延迟是痛苦的。在本地需要几分钟的大型拉取,在国际拉取时需要更长时间。我们需要限制这种延迟。更多的服务器可以解决这个问题,但会引起新问题。有了X个服务器、Y个仓库、Z个用户,并允许所有服务器同时交流可能会变得非常混乱。X越高,混乱程度就越大。中心枢纽允许我限制服务器之间的交叉通信。Git不应该以这种方式同步吗? - Jon Erickson
我在这里并没有真正减少困惑。你对高使用率的主要关注似乎是由于自动化构建,你说这些构建是基于本地存储库的,但你正在询问推送的问题。所以...有一个构建框架,它会自动检测每当有人在本地存储库中提交时,就会推送到中央存储库进行构建?然后它会在任何地方传播,无论开发人员是否想要发布该提交? - Cascabel
拥有镜像的中央仓库是完全可以的。但是,如果每个开发者的每次提交都立即推送到这些仓库,可能会导致工作流程不佳。 - Cascabel
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接