git repack多包使用及相关性能测试
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多包使用及相关性能测试相关推荐
- 2 python包、模块相关
1 ############### 调用其它路径下面的模块和包 ################################### 2 3 import sys 4 sys.path.append ...
- git打patch包及应用patch
git 打patch包和应用patch包-单个文件 打patch包 查找要打patch包的对应记录 git log 打patch包 git format-patch -1 75ca77f568bdea ...
- python 路径往上一层_Python常用模块之模块、包介绍和相关语法
在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相对较少,很 ...
- R包corrplot绘图相关系数矩阵
今天分享一个相关分析可视化实战! 之前我们分享了关于相关分析的原理,还有ggcorrplot包的使用. 相关性分析方法基础:Spearman.Kendall和Pearson R相关矩阵可视化包ggco ...
- 小姐姐用动图展示 10 大 Git 命令,包你看完过目不忘!
git merge.git rebase.git reset.git revert.git fetch.git pull.git reflog--你知道这些 git 命令执行的究竟是什么任务吗?如果你 ...
- linux安装Git依赖的包出错,技术|Linux有问必答:如何在Linux上安装Git
问题: 我尝试从一个Git公共仓库克隆项目,但出现了这样的错误提示:"git: command not found". 请问我该如何在某某发行版上安装Git? Git是一个流行的开 ...
- linux安装Git依赖的包出错,Centos6.7安装编译安装最新Git2.10.1
到 Git官网发现,git版本已经是Git2.10.1了,绝对安装最新的版本,所以我们必须采用编译安装,测试环境本地 Centos6.7,小编已经完成测试成功,在make安装时出现了错误提示,已经完美 ...
- win、linux环境下JAVA+GDAL部署,jar包启动,相关描述,问题解决
文章目录 windows环境下JAVA+GDAL 1.GDAL下载 2.GDAL安装(既解压后拷贝) 3.GDAL测试 4.Jar包方式运行 https://www.jianshu.com/p/6bc ...
- R语言包(package)以及相关命令语句
一.包 包(package)是R语言的精髓所在,通过挑选合适的包可以帮助使用者快速实现希望的功能,包可以通过http://cran.r-project.org/web/packages网站进行下载再安 ...
最新文章
- python用django连接mysql_三分钟了解Django如何连接Mysql数据库
- OpenCASCADE:STEP翻译器的介绍
- c51语言if语句多条件使用,单片机if语句判断多个条件
- JavaScript入门(part4)--简单数据类型
- date得到当前日期
- 梁迪:我为MVP骄傲,《微软最有价值专家奖励计划介绍》附专题视频
- 鸟哥的私房菜Linux 学习笔记之 Bash语法
- jdk生成keystore、tomcat配置https
- 从底层分析python中深拷贝和浅拷贝区别
- vscode开发ExtJs安装插件以及破解方法
- Arduino使用蓝牙通信模块
- 传输线阻抗方程的推导
- 原型工具Axure6.5的使用
- ln命令 Linux软连接(Symbolic Link)和硬链接(Hard Link)
- 【转】TinyXML2 入门教程
- Xilinx AXI Crossbar相关调试记录
- 一份职业游戏3D建模师日常工作流程列表,看完不信还有人说建模门槛低
- 第三章流程图与文字描述
- 超简单教你在树莓派上安装opencv(二)
- 数据分析实战项目--天猫交易数据可视化分析
热门文章
- h5 一镜到底_有哪些好的一镜到底H5案例?
- 从源码一步步学习,Ryan Dahl的Deno实现原理
- 手写签名图片处理-Android
- 在AR9331上使用Openwrt 默认开启wifi
- 无法更新运行时文件夹共享状态_Windows 10 2019 年 5 月更新 (1903_18362) 已知问题与处理进度汇总。...
- 使用rman备份到挂载的NFS目录,提示ORA-19504-27054报错
- java编程按规律输出数字图案
- php的视频怎么保存,premiere怎么保存剪辑好的视频
- 使用HttpClient访问WEB资源
- 人类图HumanDesign