用Git虛擬文件系統(tǒng)來(lái)解決大型存儲(chǔ)問(wèn)題

責(zé)任編輯:editor004

作者: Jonathan Allen

2017-03-01 11:51:56

摘自:INFOQ

 這意味著我們必須開始著手將Git增強(qiáng),讓它可以支持幾百萬(wàn)個(gè)文件,幾百G的大小,可以由幾千個(gè)開發(fā)者一起使用。因?yàn)镚VFS客戶端庫(kù)是開源的,這也是大家研究我們是如何在Windows上把虛擬文件系統(tǒng)實(shí)現(xiàn)為驅(qū)動(dòng)的好機(jī)會(huì)。

Git和GitHub上的公共存儲(chǔ)都是OSS開發(fā)的事實(shí)標(biāo)準(zhǔn)。微軟做了許多OSS開發(fā),我們想讓我們的TFS和團(tuán)隊(duì)服務(wù)等DevOps工具可以和這些工作流一起工作得很好。

我們希望微軟里所有團(tuán)隊(duì)都使用相同的版本控制系統(tǒng)。標(biāo)準(zhǔn)化將使得人們?cè)陧?xiàng)目之間轉(zhuǎn)換,以及形成資深專業(yè)經(jīng)驗(yàn)的過(guò)程變得容易。因?yàn)镺SS是捆綁到Git上的,而且我們也做了許多OSS開發(fā),那Git就自然而然的成為我們的首選了。

我們希望能響應(yīng)并支持社區(qū)和我們的DevOps客戶希望的方向。Git很明顯就是現(xiàn)代版本控制系統(tǒng)的領(lǐng)頭羊。

但如Brian Harry所說(shuō),這有一些問(wèn)題:

關(guān)于選擇Git有許多爭(zhēng)論,最主要的一個(gè)是規(guī)模問(wèn)題。沒(méi)有多少公司會(huì)有我們這么大規(guī)模的代碼庫(kù)。特別是Windows和Office(還有一些其它的),規(guī)模非常巨大。有幾千個(gè)工程師,幾百萬(wàn)個(gè)文件,幾千臺(tái)構(gòu)建服務(wù)器在不斷的構(gòu)建它——老實(shí)說(shuō),這是令人難以置信的。說(shuō)得更清楚些,當(dāng)我在這篇貼子中提到Window的時(shí)候,我實(shí)際說(shuō)的是一個(gè)非常模糊的概念,這包括了用于PC、手機(jī)、服務(wù)器、HoloLens、Xbox、物聯(lián)網(wǎng)等等方面的所有Windows系統(tǒng)。而Git是一個(gè)分布式的版本控制系統(tǒng)(distributed version control system,DVCS)。它會(huì)把整個(gè)代碼庫(kù)和所有的文件歷史都拷到你自己的機(jī)器上。要是對(duì)Windows也這么做的話會(huì)被人笑話的(事實(shí)上我們也的確被別人笑話了很多次)。TFVC和Source Depot都針對(duì)大型代碼庫(kù)和團(tuán)隊(duì)做過(guò)非常專門的優(yōu)化。Git在這樣的問(wèn)題上卻從來(lái)沒(méi)有過(guò)先例(哪怕類似規(guī)模的也行),所以很多人都斷定這種方法肯定行不通。

Reddit用戶Ruud-v-A為這個(gè)問(wèn)題提供了一些參考信息:

Linux內(nèi)核的代碼庫(kù)有1.2GB了,開發(fā)了大約12年,有5700個(gè)文件。2005年第一次提交時(shí)記錄過(guò),將整個(gè)開發(fā)歷史都導(dǎo)入進(jìn)來(lái)一共是3.2GB。3.2GB對(duì)應(yīng)5700個(gè)文件,由此推算那350萬(wàn)個(gè)文件就會(huì)需要270GB。

Chromium的代碼庫(kù)(包含了Webkit從2001年開始的歷史代碼)大小時(shí)11GB,有24.6萬(wàn)個(gè)文件。由此推算要20年并且有350萬(wàn)個(gè)文件的話,需要196GB的空間。

將Windows代碼庫(kù)拆分成合適大小的子代碼庫(kù)這條路也行不通。假如當(dāng)初一開始的時(shí)候就是這么做的,那還有可能,可是到現(xiàn)在代碼庫(kù)已經(jīng)這么大了,而且又發(fā)展了這么久,要再想回頭把它拆分開,這事實(shí)上并不可能了。Brian繼續(xù)說(shuō):

這意味著我們必須開始著手將Git增強(qiáng),讓它可以支持幾百萬(wàn)個(gè)文件,幾百G的大小,可以由幾千個(gè)開發(fā)者一起使用。同時(shí)提供一點(diǎn)參考信息,即使是Source Depot也沒(méi)辦法支持得了整個(gè)Windows的代碼庫(kù)規(guī)模。它被拆分成了40多個(gè)代碼庫(kù),所以我們才能將它擴(kuò)展,但必須在它們之上構(gòu)建一層,這樣在許多情況下,才能像使用一個(gè)代碼庫(kù)一樣使用它們。抽象當(dāng)然并不完美,有時(shí)也會(huì)造成一些沖突。

為什么不干脆把歷史版本都丟掉,然后重新開始呢?SuperImaginativeName給出了一個(gè)說(shuō)法:

NT內(nèi)核、NT的驅(qū)動(dòng)、子系統(tǒng)、API、硬件驅(qū)動(dòng)、Win32 API等,全都被其它系統(tǒng)所依賴,包括客戶。你覺(jué)得為什么你可以在Windows上運(yùn)行一個(gè)已經(jīng)開發(fā)了30年的程序呢?沒(méi)有這些歷史版本,以內(nèi)核團(tuán)隊(duì)為例,他們就不會(huì)記得15年前在一款特別的CPU上必須設(shè)置一個(gè)特殊的標(biāo)記位,因?yàn)樗闹噶罴軜?gòu)中有個(gè)小BUG,會(huì)導(dǎo)致用戶無(wú)法正常運(yùn)行某個(gè)舊的應(yīng)用程序。如果把這些歷史版本丟掉了,那也就意味著丟掉了非常大量的信息。你總不能期望每個(gè)開發(fā)者都能用腦子記住為什么一個(gè)特別的系統(tǒng)是那樣工作的。能想像某段奇怪的代碼看起來(lái)好象不怎么正確,但事實(shí)上它卻能讓你免于遭受文件損壞之苦嗎?如果只是簡(jiǎn)單地提交一個(gè)新補(bǔ)丁,再注釋上“解決了一個(gè)奇怪的問(wèn)題,真不明白為什么以前沒(méi)人發(fā)現(xiàn)它”,這么做的后果會(huì)是災(zāi)難性的。再想想去查看一下代碼歷史,然后最終恍然大悟原來(lái)這么做是有道理的,這兩種行為哪個(gè)才更正確?Windows代碼的開發(fā)是非常嚴(yán)謹(jǐn)?shù)?,所有東西都是要經(jīng)過(guò)審核的。

在經(jīng)過(guò)了若干次失敗的嘗試,包括嘗試使用Git子模塊等之后,微軟開始開發(fā)Git虛擬文件系統(tǒng)了:

我們?cè)囘^(guò)一種“虛擬化”Git的方案。通常當(dāng)你用Git克隆分支時(shí),它會(huì)把所有東西都下載下來(lái)。但如果它不下載所有東西,又會(huì)怎樣?如果我們可以把底層的存儲(chǔ)虛擬化,讓它只下載需要的東西,又會(huì)怎樣?這樣的話克隆一個(gè)巨大的300GB的代碼庫(kù)就會(huì)非??炝恕.?dāng)我執(zhí)行Git命令,或者在我的文件系統(tǒng)里讀寫文件時(shí),系統(tǒng)會(huì)無(wú)縫地從云端獲取內(nèi)容(并且將它保存在本地,這樣以后就是本地訪問(wèn)數(shù)據(jù)了)。這種方法的缺點(diǎn)在于沒(méi)有離線支持。如果你需要這一點(diǎn),你就得把所有東西“touch”一遍,假裝在本地有它們,除此之外沒(méi)有任何其它缺點(diǎn)了——你仍然會(huì)有100%一致的Git體驗(yàn)。而且對(duì)于我們的巨型代碼庫(kù)來(lái)說(shuō),這也是行得通的。

Saeed Noursalehi補(bǔ)充到:

有了GVFS,就意味著他們現(xiàn)在可以有了更好管理的Git使用體驗(yàn):每次克隆只需要花幾分鐘,而不用12多個(gè)小時(shí);檢出代碼只需要大約30秒,而不是2-3小時(shí);status命令也只需要4-5秒鐘,而不是10分鐘。而且我們還在不斷努力,讓它些數(shù)字變得更好(當(dāng)然,代價(jià)是第一次構(gòu)建會(huì)花的時(shí)間更多些,因?yàn)樗阉鼧?gòu)建的所有文件都下載下來(lái),但以后再構(gòu)建就不會(huì)比正常構(gòu)建更慢了)。

微軟對(duì)于Git的投入

要讓這種方法可以正常工作,就要改進(jìn)Git訪問(wèn)文件的方式。大家平時(shí)不一定會(huì)注意到,舊版的Git在訪問(wèn)本地存儲(chǔ)的文件時(shí),它通常會(huì)掃描比它真正需要的更多的文件。如果你去年已經(jīng)注意到微軟曾向Git OSS項(xiàng)目提交過(guò)改進(jìn)性能的代碼,這就是原因所在了。

Jeremyepling寫道:

我們微軟Git團(tuán)隊(duì)為git/git和git-for-windows做了許多貢獻(xiàn),來(lái)提高Git在Linux、Mac和Windows等上面的性能。在Git 2.10中,我們做了許多工作來(lái)使交互式Rebase操作更快。根據(jù)包含在Git源代碼中的一種基準(zhǔn)測(cè)試結(jié)果看來(lái),交互式Rebase的最終表現(xiàn)是在Windows速度提升了5倍,在MacOSX上提升了4倍,在Linux也還有3倍的提升。

對(duì)Git的一些改進(jìn)列舉如下:

sha1:在mingw上使用openssl sha1程序 https://github.com/git-for-windows/git/pull/915preload-index:對(duì)于跳過(guò)worktree的元素不使用lstat https://github.com/git-for-windows/git/pull/955memihash perf https://github.com/git-for-windows/git/pull/964add:用預(yù)加載索引和fscache來(lái)提高性能 https://github.com/git-for-windows/git/pull/971read-cache:在后臺(tái)線程中運(yùn)行verify_hdr() https://github.com/git-for-windows/git/pull/978read-cache:在檢出過(guò)程中提高add_index_entry速度 https://github.com/git-for-windows/git/pull/988string-list:在重新分配string_list時(shí)使用ALLOC_GROW宏 https://github.com/git-for-windows/git/pull/991diffcore-rename:提高register_rename_src的速度 https://github.com/git-for-windows/git/pull/996fscache:將找不到的目錄緩存加入fscache https://github.com/git-for-windows/git/pull/994

Git虛擬文件系統(tǒng)

Git虛擬文件系統(tǒng)GVFS的原型是在客戶端用一個(gè)文件系統(tǒng)驅(qū)動(dòng),以及一個(gè)支持GVFS的Git版本實(shí)現(xiàn)的。這需要“Windows 10周年”版,或更新的版本。只要Git庫(kù)支持了GVFS,那平時(shí)常用的Git命令就仍可以照常使用。GVFS子系統(tǒng)基于文件系統(tǒng)工作,它會(huì)在背后從服務(wù)器下載任何你需要的文件。

因?yàn)镚VFS客戶端庫(kù)是開源的,這也是大家研究我們是如何在Windows上把虛擬文件系統(tǒng)實(shí)現(xiàn)為驅(qū)動(dòng)的好機(jī)會(huì)。

在服務(wù)器端,你需要一些實(shí)現(xiàn)GVFS協(xié)議的東西?,F(xiàn)在,這指的是Visual Studio團(tuán)隊(duì)服務(wù),這協(xié)議是開源的,所以別的服務(wù)提供商也可以提供相同的能力。GVFS協(xié)議本身也是很簡(jiǎn)單的,包含四個(gè)類REST的接口。

鏈接已復(fù)制,快去分享吧

企業(yè)網(wǎng)版權(quán)所有?2010-2024 京ICP備09108050號(hào)-6京公網(wǎng)安備 11010502049343號(hào)