我最近设置了一个小型 turnkeylinux 版本控制虚拟机(大约有 256MB RAM),并尝试克隆我推送到它的一个存储库。推送速度非常快(通过 ssh),但提取速度极慢。
如果我将其留到 SSH 超时,则会得到以下结果:
$ git pull
[email protected]'s password:
remote: Counting objects: 403, done.
Read from remote host 1.2.3.4: The connection was aborted
fatal: The remote end hung up unexpectedly
fatal: early EOF
我尝试如下方式克隆:
> mkdir myProj
> cd myProj
> git init
> git remote add origin git+ssh://[email protected]/srv/repos/git/myProj
> git pull
当我发出拉动命令时,它几乎立即达到 50%,然后停止。它慢慢地向前爬动几个百分点(一次尝试达到 66%),如果停留时间足够长,最终会停止。
这个 repo 很小,到目前为止只有少数几个修订版本。我的主要 repo 大得多,除非确定了这个问题,否则也将无法使用。
有什么想法可能导致突然减速吗?
更新
我刚刚确认,使用 git:// 协议连接时,VM 也运行缓慢。因此,这不可能是 ssh 的问题。相应地更新问题标题。
答案1
file:
您是否能够使用协议存储库 URL在 VM 上进行本地克隆?
git clone file:///srv/repos/git/myProj /tmp/myProj-clone
该file:
协议强制本地操作使用与git:
/ ssh:
/smart-http:
远程 URL 使用的常规智能协议非常接近的协议。具体来说,它使用基于包的协议,而不是利用本地操作的常规优化(存储库对象的硬链接/复制)。
您的服务器可能没有足够的内存来生成拉取操作所需的包。进行试验性的本地file:
克隆/拉取将测试您的虚拟机的包生成能力,而无需拖入任何类型的网络组件来混淆问题。
有几个配置变量控制包的生成:
- 包装窗口
- 包装深度
- pack.window内存
- pack.deltaCacheSize
- pack.deltaCacheLimit
您也许能够调整您的存储库以用内存密集程度较低的方式生成其包(但打包效率可能会因此受到影响)。
我的猜测是 256MB(对于操作系统和应用程序而言?)太小了,无法期望(潜在的)占用大量内存的应用程序(例如 Git 的打包操作)快速甚至正确地运行。
答案2
登录到 1.2.3.4 并 cd 到你的 git repo 并执行“git repack”;然后尝试拉取并看看是否有帮助。
答案3
尝试在服务器上禁用 TCP 分段卸载-> ethtool -K eth0 tso off
答案4
如果您没有(足够的)交换空间并且 OOM Killer 启动,那么 256 MB 最终可能会变成小内存。您是否检查过 VM 系统的日志中是否有被杀死的程序?磁盘上的存储库(.git
非裸存储库的目录)有多大?
请注意,git
实现方式是,存储库中最大的对象(例如 ISO 映像)必须同时作为解压缩和 [git] 压缩数据在内存中可用,以便通过网络传输数据(git pack 数据传输)。存储库中包含的单个高度压缩的 200MB 二进制 blob(例如 H.264 视频)将使从该机器获取/拉取/克隆至少占用约 400MB 的内存。如果您的系统只有 256MB 的内存用于整个系统,那么您将需要大约 140MB 的额外内存用于 git,再加上操作系统从交换中所需的所有内存。如果有足够的交换空间,它将工作,但速度会非常慢。
Git 针对可以在 RAM 中保存至少 10 个最大对象的系统进行了高度优化。如果您要处理大量小文件(例如 Linux 内核),那么只有 256MB 内存的系统就足够了,但如果您有一个大文件,交换就会停止。对于大量小文件的情况,内存需求似乎约为 160 字节乘以存储库中的对象数。要了解对象数,请运行git count-objects -v
并计算和的总和count
。in-pack
拥有的对象越多,in-pack
git 占用的磁盘空间就越少。
如果你想使用 git 来处理包含巨大二进制文件的项目和你的 git 存储库机器内存有限,请遵循 git 对“松散对象”的开发。
来源:http://git.661346.n2.nabble.com/pack-operation-is-thrashing-my-server-td684437.html