GIT 存儲服務性能分析與優化

原文連接 https://wxaxiaoyao.cn/article/105git

Git 本質是一套內容尋址 (content-addressable) 文件系統, 但因爲其將內容哈希成一個 sha 做爲索引, 故也稱對象存儲或鍵值存儲(key-value-store).性能優化

背景介紹

如今不少產品都帶有歷史回退功能, 筆記產品尤其常見, 這也是很是重要的, 特別對於一些文字工做相關的, 常常會寫一些東西而後改來改去, 最後發現仍是以前的寫的好, 這時想回退舊版本, 就必須記錄歷史.併發

GIT 歷史實現原理

git 有三類對象blob, tree, commit, 這三類會以文件形式存儲在 git 根目錄下 objects 目錄中, 每一個對象都會有個對應的索引哈希值(sha), 哈希值(sha) 幾乎等同於其文件名(前兩位爲目錄, 後面部分爲文件名).性能

  • blob 對應倉庫中的文件.
  • tree 對應目錄, 包含blob索引值和以及子tree索引值. 所以根 tree 便記錄整個倉庫的文件信息.
  • commit 對應版本, 其內容包含當前版本根tree索引, 以及上次commit索引, 以及其它提交信息. 因爲commit存在上次commit索引, 即可造成整個commit鏈, 也是提交歷史.

文件回退流程:優化

  1. 遍歷 commit 鏈, 選擇須要的版本提交點.
  2. 經過 commit 記錄的根tree索引, 獲取指定版本的文件樹, 遞歸遍歷查找指定文件項
  3. 根據文件項記錄的記錄的文件索引去讀取文件內容.

詳細原理分析可讀此篇文章: GIT 原理分析對象

index 文件

以根tree爲起點是能夠遞歸獲取整個倉庫的文件索引信息的, 但每一個tree都是一個文件, 經過tree去獲取會不停的讀文件, 性能不好. 爲此git 會將整個倉庫的文件索引信息單獨記錄在一個index文件中,
每次經過讀取index文件內容來獲取整個倉庫的文件記錄.遞歸

git 服務性能問題

因爲git經過index文件記錄倉庫的文件信息. 所以當倉庫的文件數越多, index 文件大小就越大, git 服務程序越佔內存. 同時因爲要保證index文件正確性, git 服務是無法支持併發寫同一個倉庫的多個文件.
當併發寫多個倉庫的文件時, 程序會同時加載多個倉庫的index文件到內存. 而硬件內容是有限的, 所以index文件大小也直接影響到併發寫多個倉庫的數量. 因而可知倉庫文件數過多確實會影響git服務的性能.索引

git 服務性能優化

git 本職功能是代碼管理, 若 git 服務僅用於代碼管的話, 其性能問題其實還好, 由於沒有併發寫同一倉庫的問題存在. 可是將 git服務 做爲普通的存儲服務, 那麼併發寫同一倉庫的可能性會很高(倉庫內容越多, 可能性也越高).
也許有人會說 git 不適合此種場景, 本文暫不討論此說法, 是創建 git 作存儲服務上討論. 解決 git 性能最好的辦法即是下降單倉庫的文件數, 而做爲普通的存儲服務關心的是單文件的歷史, 並不關心整個倉庫的總體的歷史.
因此下降單倉庫的思路是可行的. 而下降單倉庫的文件數又便於管理直接辦法即是: 目錄即倉庫, 將全部目錄都初始化爲倉庫, 同時限制單目錄(倉庫)的文件數.內存

TODO

  • 其它拆庫方案
  • 單庫文件數過多時, 程序是否能夠自動拆庫, 下降客戶端心智負擔.
相關文章
相關標籤/搜索