1、git数据结构

git 中存在四种数据结构,即object包含四种,分别是tree对象、blob对象、commit对象、tag对象

1.1 blob对象

存储文件内容,内容是二进制的形式,通过SHA-1算法对文件内容和头信息进行计算得到key(文件名)。
如果一个commitId为73c17abe44977ee82cd949f489996c2715335119,则这个blob文件在.git/objects/73文件夹下,名为c17abe44977ee82cd949f489996c2715335119,也就是说hash值的前两位为objects目录下子目录的名字,剩余38位为文件名。

1.2 tree对象

可以看作一个目录,管理一些“tree”对象或是“blob”对象。它有一串指向“blob”对象或是其它“tree”对象的指针,一般用来表示内容之间的目录层次关系(就像文件和子目录)

1.3 commit对象:

commit对象指向一个“tree对象”,并且带有相关的描述信息,标记项目某一个特定时间点的状态。它包括一些关于时间点的元数据,如时间戳、最近一次提交的作者、指向上次提交的指针等

commit、tree、blob关系可以总结如下:
一个commit对应一个tree对应多个blob

1.4 tag对象:

一个tag对象包括一个对象名(SHA1签名)、对象类型、标签名、标签创建人的名字(“tagger”), 还有一条可能包含有签名(signature)的消息。
通过

总结

git每次提交存储的都是整个文件,而不是采用增量,所以会导致存储数据量很大,git针对此采用了zlib对数据进行压缩,可以采用cat-file命令来查看

一旦将内容存储在了对象数据库中,那么可以通过 cat-file 命令从 Git 那里取回数据。 为 cat-file 指定 -p 选项可指示该命令自动判断内容的类型,并为我们显示大致的内容:

2、git pack

git向仓库中推送文件时存储使用的是“松散文件”,如果有一个1.txt现在是10k,下次推送增加了0.1k,也就是说现在是10.1k,name第二个版本就会重新产生一个1.1k的文件,这样会产生磁盘浪费,所以git会将这些文件打包成一个二进制类型的包文件(packfile),并生成对应的.idx索引文件,以节省空间和提升效率。这些被打包的文件存储在.git/objects/pack目录下,执行find .git/objects/ -type f命令如下

看到.git/objects目录下的文件详情,包含了8个松散文件、一个pack文件、一个idx文件,如果想查看更详细的内容可以执行
git count-objects -v命令

git count-objects -v命令结果的各个含义如下:

  • count: 松散对象数
  • size:松散对象占用的磁盘空间,单位为KB
  • in-pack:在pack文件中的objects数量
  • size-pack:pack文件占用的空间,单位为KB
  • prune-packable:同时在松散对象和packs文件中都包含的objects数量,这种objects可以执行git prune-packed命令修剪
  • garbage:对象数据库中既不是有效松散对象也不是有效包的文件数
  • size-garbage:垃圾文件占用的磁盘空间,单位为KB

3、git repack

3.1 repack作用

用于将当前不驻留在“pack”中的所有对象合并到包中。它还可用于将现有包重新组织为一个更高效的包。pack文件是单独压缩的对象的集合,应用了增量压缩,存储在单个文件中,并具有关联的索引文件。而且pack文件用于减少镜像系统、备份引擎、磁盘存储等上的负载。

3.2 单包与多包

3.2.1 单包

在重新打包时repack会有一些options可供选择,如-d, -A,如果加上了-A,则重新打包时就会将新的松散文件与之前的pack共同打包成一个pack。

在单包时通常会将加上--write-bitmap-index来生成.bitmap文件(bitmap文件存储有关包文件或多包索引(MIDX)中对象集的可达性信息),此option会覆盖repack.writeBitmaps值,当然如果不指定此option,也可通过命令git config --global repack.writeBitmaps true,然后通过git config -l查看是否成功设置此option。需要注意的是--write-bitmap-index option只在单包时才会生效,也就是说只在与-a、-A或-m一起使用时有意义,因为位图必须能够引用所有可访问的对象(多包如何设置bitmap后面会涉及)。

3.2.2 多包

随着文件数越来越多,pack文件就会越来越大,单包策略的缺点就暴露了出来,如果使用单包,包大小高达30g甚至更大,当有新的松散文件时、或gc时,触发的repack将会非常慢。

针对上述问题,可以采用多包的方式,为每个packfile设置一个限制(pack.packSizeLimit),超过这个限制就分包,同时每次repack重新打包时将新的松散对象采用增量(git repack -d)打包,然后在于之前的小于某个限制(git multi-pack-index repack --batch-size=<size>)的所有pack重新打包,看下如下命令:

# 设置每个packfile的大小为3g,-d表示采用增量的方式将新松散文件打包,使用--write-midx 开启多包索引
git -c pack.threads=4 -c pack.packSizeLimit=3g -c repack.packKeptObjects=true -c core.multiPackIndex=true repack -l -d -n --write-midx # git multi-pack-index repack --batch-size=<size>,将小于size的packfile重新打包成一个或多个packfile,如果两个packfile都小于size打小,但是重新repack后生成的新packfile大于pack.packSizeLimit,那么将不予合并打包
git -c pack.threads=4 -c repack.packKeptObjects=true -c pack.packSizeLimit=3g -c core.multiPackIndex=true multi-pack-index repack --batch-size=2g # 重新生成bitmap
git multi-pack-index write --bitmap

3.3 repack单包与多包性能对比

当测试repack相关功能时,为了验证单包和多包性能问题,需要保持每次松散对象数量是一致的,因此当执行完单包命令之前需要将objects文件夹备份,并在执行完单包命令之后将备份的objects重新复制回去并执行unpack命令,流程如下:

3.3.1 前置条件:

已有40w个松散对象被打包成一个pack(约7.5g),以及10w个松散对象(约2g)。本次通过直接执行命令观看效果,因此使用了root权限。

  • 1、将.git/objects整个目录备份,并将10w个文件产生的对应的pack(记为pack-d69d44271fc40005eed5c8e0d7ec82c15e80dddd.pack)文件备份
  • 2、执行cat pack-d69d44271fc40005eed5c8e0d7ec82c15e80dddd.pack | git unpack-objects,将pack-d69d44271fc40005eed5c8e0d7ec82c15e80dddd.pack重新unpack成loose objects,需要注意的是执行unpack-objects命令的pack需要从.git/objects目录下移走
  • 3、验证单包/多包命令
  • 4、回到步骤2循环执行
3.3.2 测试命令

测试时可参考下述命令
单包

  • gc:
git -c repack.writeBitmaps=true -c pack.writeBitmapHashCache=true  -c gc.writeCommitGraph=false gc --prune=30.minutes.ago
  • repack
git -c pack.threads=16 -c repack.writeBitmaps=true repack -A -l -d -n

多包

  • gc
git -c pack.packSizeLimit=3g -c repack.packKeptObjects=true -c gc.writeCommitGraph=false -c gc.bigPackThreshold=2g gc --prune=30.minutes.agogit multi-pack-index write --bitmap
  • repack
git multi-pack-index expire git -c pack.threads=16 -c pack.packSizeLimit=3g -c repack.packKeptObjects=true -c core.multiPackIndex=true repack -l -d -n --write-midx git -c pack.threads=16 -c repack.packKeptObjects=true -c pack.packSizeLimit=3g -c core.multiPackIndex=true multi-pack-index repack --batch-size=2g git multi-pack-index write --bitmap
3.3.3 测试结果及分析
1、耗时分析
  • 单包repack
  • 多包repack

    重写bitmap耗时约1m 18s

    可以看到多包repack总耗时约在4m 42s
2、cpu分析

左边是单包,右边是多包

可以看到单包时cpu使用超50%耗时约420s,而多包则在140s

3、IO读写

总结

整理IO读写并进行估算后,结果如下(旧逻辑即为单包,新逻辑即为多包)

绘图如下

可以看到使用多包处理后资源占用明显降低,耗时减少。

相关文档

1、Git-内部原理-Git-对象
2、git-gc
3、git-config
4、git-pack-objects
5、git-multi-pack-index
6、git-repack
7、git-count-objects
8、bitmap
9、Git数据存储的原理浅析

git repack多包使用及相关性能测试相关推荐

  1. 2 python包、模块相关

    1 ############### 调用其它路径下面的模块和包 ################################### 2 3 import sys 4 sys.path.append ...

  2. git打patch包及应用patch

    git 打patch包和应用patch包-单个文件 打patch包 查找要打patch包的对应记录 git log 打patch包 git format-patch -1 75ca77f568bdea ...

  3. python 路径往上一层_Python常用模块之模块、包介绍和相关语法

    在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很 ...

  4. R包corrplot绘图相关系数矩阵

    今天分享一个相关分析可视化实战! 之前我们分享了关于相关分析的原理,还有ggcorrplot包的使用. 相关性分析方法基础:Spearman.Kendall和Pearson R相关矩阵可视化包ggco ...

  5. 小姐姐用动图展示 10 大 Git 命令,包你看完过目不忘!

    git merge.git rebase.git reset.git revert.git fetch.git pull.git reflog--你知道这些 git 命令执行的究竟是什么任务吗?如果你 ...

  6. linux安装Git依赖的包出错,技术|Linux有问必答:如何在Linux上安装Git

    问题: 我尝试从一个Git公共仓库克隆项目,但出现了这样的错误提示:"git: command not found". 请问我该如何在某某发行版上安装Git? Git是一个流行的开 ...

  7. linux安装Git依赖的包出错,Centos6.7安装编译安装最新Git2.10.1

    到 Git官网发现,git版本已经是Git2.10.1了,绝对安装最新的版本,所以我们必须采用编译安装,测试环境本地 Centos6.7,小编已经完成测试成功,在make安装时出现了错误提示,已经完美 ...

  8. win、linux环境下JAVA+GDAL部署,jar包启动,相关描述,问题解决

    文章目录 windows环境下JAVA+GDAL 1.GDAL下载 2.GDAL安装(既解压后拷贝) 3.GDAL测试 4.Jar包方式运行 https://www.jianshu.com/p/6bc ...

  9. R语言包(package)以及相关命令语句

    一.包 包(package)是R语言的精髓所在,通过挑选合适的包可以帮助使用者快速实现希望的功能,包可以通过http://cran.r-project.org/web/packages网站进行下载再安 ...

最新文章

  1. python用django连接mysql_三分钟了解Django如何连接Mysql数据库
  2. OpenCASCADE:STEP翻译器的介绍
  3. c51语言if语句多条件使用,单片机if语句判断多个条件
  4. JavaScript入门(part4)--简单数据类型
  5. date得到当前日期
  6. 梁迪:我为MVP骄傲,《微软最有价值专家奖励计划介绍》附专题视频
  7. 鸟哥的私房菜Linux 学习笔记之 Bash语法
  8. jdk生成keystore、tomcat配置https
  9. 从底层分析python中深拷贝和浅拷贝区别
  10. vscode开发ExtJs安装插件以及破解方法
  11. Arduino使用蓝牙通信模块
  12. 传输线阻抗方程的推导
  13. 原型工具Axure6.5的使用
  14. ln命令 Linux软连接(Symbolic Link)和硬链接(Hard Link)
  15. 【转】TinyXML2 入门教程
  16. Xilinx AXI Crossbar相关调试记录
  17. 一份职业游戏3D建模师日常工作流程列表,看完不信还有人说建模门槛低
  18. 第三章流程图与文字描述
  19. 超简单教你在树莓派上安装opencv(二)
  20. 数据分析实战项目--天猫交易数据可视化分析

热门文章

  1. h5 一镜到底_有哪些好的一镜到底H5案例?
  2. 从源码一步步学习,Ryan Dahl的Deno实现原理
  3. 手写签名图片处理-Android
  4. 在AR9331上使用Openwrt 默认开启wifi
  5. 无法更新运行时文件夹共享状态_Windows 10 2019 年 5 月更新 (1903_18362) 已知问题与处理进度汇总。...
  6. 使用rman备份到挂载的NFS目录,提示ORA-19504-27054报错
  7. java编程按规律输出数字图案
  8. php的视频怎么保存,premiere怎么保存剪辑好的视频
  9. 使用HttpClient访问WEB资源
  10. 人类图HumanDesign