Google 的 Git v2 带来颠覆性性能提升?恐怕未必

Stella981
• 阅读 708

作者简介

王振威,CODING 创始团队成员之一,多年系统软件开发经验,擅长 Linux,Golang,Java,Ruby,Docker 等技术领域,近两年来一直在 CODING 从事系统架构和运维工作

前言

最近 Google 发布了一篇文章,描述了对 Git 的一个传输协议的更新,引起了国内技术圈的不小规模的轰动(相关文章请自行百度“Git v2 性能提升”)。 很多技术圈的朋友也在转载这个新闻,那至于性能改进有多大,里面的细节是什么呢?事实上这次改动只在极端情况下有性能提升,绝大多数情况下,用户感受不到性能的提升。很多不明所以的转发大概是因为 Google 的品牌效应吧 :)

Git 是什么?

为了讲清楚 why,我们先来简单介绍一下 Git 相关的协议。如果你还不了解 Git,想了解更多内容,可参考其官方网站:http://git-scm.com/ . 也可来 https://coding.net/help/doc/git 这里了解如何在国内使用优质快速的 Git 托管服务。

Git 传输协议

Git 常见的有三种协议,SSH,HTTP(S),Git,使用最广泛的是前两种。

让我们来看一下, HTTP(S) 和 SSH 协议的使用示例

git clone https://git.coding.net/wzw/coding-demo.git

Cloning into 'coding-demo'...

remote: Counting objects: 3, done.

remote: Total 3 (delta 0), reused 0 (delta 0)

Unpacking objects: 100% (3/3), done.

git clone git@git.coding.net:wzw/coding-demo.git

Cloning into 'coding-demo'...

remote: Counting objects: 3, done.

remote: Total 3 (delta 0), reused 0 (delta 0)

Receiving objects: 100% (3/3), done.

可以看到,对于全新 clone 来讲两者基本上的过程是一模一样的。

事实上, Git 底层对于各种应用层协议的底层处理是一致的,不管是 HTTP(S) 还是 SSH 还是 Git 协议。

让我们来进一步看一下, Git 在传输过程中都做了什么。

GIT_TRACE=1 GIT_TRACE_PACKET=1 git clone https://git.coding.net/wzw/coding-demo.git

17:48:21.767799 git.c:344               trace: built-in: git 'clone' 'https://git.coding.net/wzw/coding-demo.git'

Cloning into 'coding-demo'...

17:48:21.797959 run-command.c:626       trace: run_command: 'git-remote-https' 'origin' 'https://git.coding.net/wzw/coding-demo.git'

17:48:22.278880 pkt-line.c:80           packet:          git< # service=git-upload-pack

17:48:22.279390 pkt-line.c:80           packet:          git< 0000

17:48:22.279405 pkt-line.c:80           packet:          git< fdacba1d541c75bd48f2cd742ee18f77ea3517a1 HEAD\0multi_ack thin-pack side-band side-band-64k ofs-delta shallow deepen-since deepen-not deepen-relative no-progress include-tag multi_ack_detailed no-done symref=HEAD:refs/heads/master agent=git/2.15.0

17:48:22.279419 pkt-line.c:80           packet:          git< fdacba1d541c75bd48f2cd742ee18f77ea3517a1 refs/heads/master

17:48:22.279431 pkt-line.c:80           packet:  

Google 的 Git v2 带来颠覆性性能提升?恐怕未必

好,基础知识补充完毕,有没有发现火爆的区块链在技术层面上跟 Git 的存储是有相似之处的 :)

在 Clone 过程中,服务器端首先会推荐给客户端一些 ref 列表,这也是 Git v2 协议号称的性能改进的地方,后文有解释。

像这样:

17:49:19.772436 pkt-line.c:80           packet:        clone< fdacba1d541c75bd48f2cd742ee18f77ea3517a1 refs/heads/master

17:49:19.772527 pkt-line.c:80           packet:        clone< 1536ad10fc0a188c50680932ca191c8da46938c4 refs/heads/test-abc

17:49:19.772549 pkt-line.c:80           packet:        clone< 1536ad10fc0a188c50680932ca191c8da46938c4 refs/heads/test-bcd

17:49:19.772566 pkt-line.c:80           packet:        clone< 30eb4b0d813c662c4d7e87c4d3b4cf561e544f8e refs/tags/v1.0

17:49:19.772863 pkt-line.c:80           packet:        clone< 1536ad10fc0a188c50680932ca191c8da46938c4 refs/tags/v1.0^{}

很显然,上文中的 40 位16进制数字就是对应后面的 ref 指向的对象 ID。

而客户端,只需要依据自己感兴趣的 ref 和自己本地已经存在的对象库(对于 pull 和 fetch 来讲,本地有对象库,对于 clone 来讲本地还没有对象库,那么他就是需要所有的感兴趣的对象)。

在客户端计算完毕自己感兴趣的对象列表后,会用 want 指令告诉远端服务器。

17:49:19.776185 pkt-line.c:80           packet:        clone> want fdacba1d541c75bd48f2cd742ee18f77ea3517a1 multi_ack_detailed side-band-64k thin-pack ofs-delta deepen-since deepen-not agent=git/2.15.1.(Apple.Git-101)

17:49:19.776215 pkt-line.c:80           packet:        clone> want fdacba1d541c75bd48f2cd742ee18f77ea3517a1

17:49:19.776224 pkt-line.c:80           packet:        clone> want 1536ad10fc0a188c50680932ca191c8da46938c4

17:49:19.776232 pkt-line.c:80           packet:        clone> want 1536ad10fc0a188c50680932ca191c8da46938c4

17:49:19.776239 pkt-line.c:80           packet:        clone> want 30eb4b0d813c662c4d7e87c4d3b4cf561e544f8e

如果客户端执行的是 pull 或者 fetch ,他还会告诉远端自己已经有了什么对象(在文章的后面,我们会补充一段专门说明此点)。

远端服务器会根据客户端想要的对象以及客户端已经有的对象并对比自身的对象库和对象依赖关系,将客户端必须的对象整理起来并打包压缩传给客户端。

客户端收到对象包后,解包并校验对象,并更新引用的对应指向。

Google 在 Protocol version 2 做了什么

完整的 version 2 的协议说明在这里: https://www.kernel.org/pub/software/scm/git/docs/technical/protocol-v2.html

这里我们对其做的主要改动做些说明,主要有三点:

服务端引用过滤

新特性的易扩展性升级(例如可声明想要什么 ref)

简化的客户端 HTTP 协议处理

被很多标题党夸大其词的主要是其第一点:服务端引用过滤。

Google 官方的博客中对此段的描述是这样的:

The main motivation for the new protocol was to enable server sid

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这