炼数成金 门户 大数据 开源软件 查看内容

Google宣布Git协议迎来重大更新,性能大幅提升

2018-5-21 10:13| 发布者: 炼数成金_小数| 查看: 13859| 评论: 0|来自: 聊聊架构

摘要: Git 团队最近为谷歌提供协议 v2 支持,他们发现,在包含 50 万个引用的仓库中,单个分支 fetch 操作的性能提高了 3 倍。协议 v2 还将从 googlesource.com 服务器发送出来的字节数减少到原先的八分之一。这项改进要归 ...

安全 Hadoop 服务器 培训 RAC

来自 Git 团队的 Brandon Williams 在博客上宣布正式推出 Git 协议 v2,这是对 Git 线路协议(wire protocol)的一个重大更新。此次更新移除了 Git 协议中较低效的部分,修复了一个扩展性瓶颈问题,并为未来更多的线路协议改进提供可能性。

协议 v2 的规范可以https://www.kernel.org/pub/software/scm/git/docs/technical/protocol-v2.html 找到。主要改进包括:
服务器端的引用过滤。
扩展新特性变得更容易,如 ref-in-want 及 symref 的拉取和推送。

简化 HTTP 客户端处理。
新版本协议的主要目标是支持服务器端引用(分支和标签)过滤。在协议 v2 之前,服务器在向 fetch 命令做出响应时,会列出仓库中所有的引用。即使客户端只想更新单个分支,例如“git fetch origin master”,服务器端也会向它发送整个引用清单。

对于包含成千上万个引用的仓库(Chromium 仓库有超过 50 万个分支和标签),服务器可能会发送数十兆字节的数据,而这些数据最终将被忽略。这通常会浪费时间和带宽,特别是在更新只包含少量提交的远程分支时,或者有时候只想检查代码是否是的。

Git 团队最近为谷歌提供协议 v2 支持,他们发现,在包含 50 万个引用的仓库中,单个分支 fetch 操作的性能提高了 3 倍。协议 v2 还将从 googlesource.com 服务器发送出来的字节数减少到原先的八分之一。这项改进要归功于服务器端对引用进行了过滤,只返回客户端需要的引用。

克服障碍
在过去几年,Git 项目多次尝试限制初始引用,或者使用新的协议,但仍然存在两个问题:
初始请求太过死板,请求消息里不包含这样的一个字段,可用于在不破坏与现有服务器兼容性的情况下请求新服务器修改响应消息。
错误处理机制不够完善,无法在现有服务器不兼容新协议时安全快速地回退到旧协议。

为了迁移到新的协议版本,Git 团队需要找到一种方式,既可以让现有服务器忽略不兼容部分,又可以安全地与新服务器通信。

Git 的连线协议包含了三种主要的传输方式(Git://、ssh:// 和 https://)。HTTP 传输方式是最简单的,可以在请求中包含额外的 HTTP 消息头(如“Git-Protocol: version=2”)。SSH 传输方式稍难一些,因为它需要将一个环境变量(如“GIT_PROTOCOL=version=2”)发送到远程终端上。这更具有挑战性,因为它要求管理员在服务器端配置 sshd,这样才能接收到新的环境变量。最难的传输方式是匿名 Git 传输(Git://)。

使用匿名 Git 传输方式向服务器发出的初始请求使用了单个 packet-line 的格式,其中包含了请求的服务和仓库地址,后面再跟上一个 NUL 字节。后来又添加了虚拟化支持,并且可以附加主机名参数,并使用 NUL 字节作为结束符:“0033git-upload-pack /project.git\0host=myserver.com\0”。在理想情况下,可以添加一个新的参数来发起协议 v2 请求,就像添加主机名那样:“003dgit-upload-pack /project.git\0host=myserver.com\0version=2\0”。
可惜的是,由于在 2006 年引入了一个 bug,导致不能添加主机名以外的任何参数,否则在解析这些参数时将进入一个死循环。这个 bug 在 2009 年得到了修复,添加了一个检查条件,不允许添加额外的参数,这样新客户就不会在老服务器上触发这个 bug。

幸运的是,如果在第二个 NUL 字节后面放置额外的请求参数,这个检查条件就不会注意到。请求可以变成这样:“003egit-upload-pack /project.git\0host=myserver.com\0\0version=2\0”。通过在第二个 NUL 字节后面放置版本信息,就可以绕过死循环错误,同时又可以添加新的参数。只有新服务器知道如何找到隐藏在两个 NUL 字节后面的附加信息,而旧服务器不会发出任何警告。

现在,客户端可以发起使用协议 v2 的请求,协议 v2 服务器可以使用新的协议做出响应,而旧服务器则会忽略它们。

动手体验
要想体验一下协议 v2,需要安装 Git 的版本(支持协议 v2 的代码已经合并到 Git master 分支,预计作为 Git 2.18 的一部分)和启用了协议 v2 的服务器(googlesource.com 和 Cloud Source 上的仓库已经启用了协议 v2)。如果启用了追踪选项,在发送“ls-remote”命令查询单个分支时,可以看到服务器发送的引用数量要小得多。

# 使用旧协议
GIT_TRACE_PACKET=1 git -c protocol.version=0 ls-remote 
https://chromium.googlesource.com/chromium/src.git master

# 使用新协议
GIT_TRACE_PACKET=1 git -c protocol.version=2 ls-remote 
https://chromium.googlesource.com/chromium/src.git master

如果,Google 早已解决不了你的问题。
如果,你还想知道 Apple、Facebook、IBM、阿里等国内外名企的核心架构设计。

欢迎加入本站公开兴趣群
软件开发技术群
兴趣范围包括:Java,C/C++,Python,PHP,Ruby,shell等各种语言开发经验交流,各种框架使用,外包项目机会,学习、培训、跳槽等交流
QQ群:26931708

Hadoop源代码研究群
兴趣范围包括:Hadoop源代码解读,改进,优化,分布式系统场景定制,与Hadoop有关的各种开源项目,总之就是玩转Hadoop
QQ群:288410967 

鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

热门频道

  • 大数据
  • 商业智能
  • 量化投资
  • 科学探索
  • 创业

即将开课

 

GMT+8, 2018-8-22 12:19 , Processed in 0.175837 second(s), 26 queries .