寫在前面:大約在2013年,谷歌的源代碼控制系統每天為超過25000名開發者提供服務,所有這些服務都來自于藏身于樓梯角落的一台伺服器。
故事開端:一切從單一Perforce伺服器開始
2011年,時任谷歌Perforce管理團隊技術主管的Dan Bloch發表了一篇題為《依然全在一伺服器上:大規模下的Perforce(Still All On One Server: Perforce at Scale)》的論文。該論文詳細闡述了谷歌的源代碼控制系統,即便每天為“超過12000名使用者”提供服務,仍舊隻依賴位于主校區43号樓樓梯下方的一台單一Perforce伺服器。
截至2011年,這台單一伺服器已經在谷歌的曆史中連續運作了十一年之久。它見證了初創時期的谷歌,并成功擴充以支援如今的上市公司谷歌。事實上,就在那時,一位幸運的谷歌工程師剛剛完成了第2000萬次變更請求。伺服器依舊穩定運作,每日執行“1100萬至1200萬條指令”。
在論文中,Bloch描述了一些成功實作伺服器擴充的舉措。然而,實際情況并非如此樂觀。
如今的谷歌早已脫胎換骨,不再是那個初出茅廬的小企業。随着實力的壯大,谷歌投入重金,裝配了一系列業界頂尖的硬體設施。然而,即便坐擁如此強大的硬體支援,其伺服器仍時常面臨嚴峻考驗,承載的壓力不容小觑。在CPU使用率觸頂的高峰時段,系統偶爾會遭遇TCP連接配接中斷的困擾。為防患于未然,確定萬無一失,谷歌始終保持一台熱備份伺服器随時待命,與此同時,一支由八名專業管理者構成的精幹隊伍全天候值守,随時準備采取應急措施,力保源代碼控制伺服器的平穩運作,避免任何可能影響谷歌日常運作的意外發生。
多年來,谷歌内部一直意識到這是一個潛在風險,工程師們也在尋找替代方案。但在谷歌這樣的規模——“地球上最繁忙的單一Perforce伺服器,以及任何源代碼控制系統中最大的存儲庫之一”——并沒有明确的替代選擇。
遙想當年,Linus之是以在2005年建立git,就是因為他找不到任何能夠有效應對Linux核心倉庫龐大體量的解決方案。
在谷歌于2011年釋出《依然全在一伺服器上:大規模下的Perforce》論文後的幾年裡,這家科技巨頭公開披露了其單一倉庫中驚人的代碼變更規模。具體到2014年,谷歌的單一倉庫每周會經曆約1500萬行代碼的變化,涉及大約25萬個檔案的修改。
為幫助你直覺感受這一數字的震撼,不妨将其類比為每周都要從零開始重構整個2014版的Linux核心——而這距離Linus首次直面核心管理挑戰,已過去了整整九年。
少有人走的路:堅持單一倉庫的決策,孤注一擲選擇Piper
自2008年起,谷歌的工程師們就開始考慮對這台單一伺服器的替代方案。
他們一度考慮過拆分單一倉庫的想法,但最終否決了這一方案——事後看來,這是一個重大的、具有行業變革意義的決定,因為它為未來幾十年大規模處理代碼複雜性設定了标準。
此後數年間,谷歌發明并引領了許多大型單一倉庫工具的發展,并顯著影響了單一倉庫文化的普及。(例如,可以參閱其2016年的論文,《為何谷歌将數十億行代碼存儲在單一倉庫中》。)
然而,當時繼續堅持單一倉庫的決策并不是一個顯而易見的選擇。直到這一刻,谷歌的單一倉庫架構相對自然地發展起來;這是第一次迫使組織必須明确承諾采用這一架構。這一決定與當時Git社群盛行的觀點形成了鮮明對比:人們應該擁有“更多且更小的倉庫”,部分原因在于克隆龐大單一倉庫所帶來的高昂成本(後來,谷歌通過SourceFS和雲用戶端(Clients in the Cloud,簡稱CitC)等工具解決了這個問題)。如果谷歌選擇了遵循正常,而不是明确肯定對單一倉庫架構的承諾,今天的局面可能大相徑庭。
谷歌也曾短暫考慮過從Perforce遷移到SVN,認為SVN或許能夠滿足他們所需的規模。然而,當工程師們發現沒有清晰的遷移路徑時,這一設想并未成功。
最終,如同Linus在2005年所做的一樣,唯一的前進道路似乎就是創造全新的東西。
這套新系統被稱為Piper(源自某些工程師對飛機的喜愛,同時也是“Piper is Piper expanded recursively”的縮寫),至今仍在使用中。
遷移:耗時四年的“移山”之旅
一旦工程師們确定了替代方案的大緻形态(Piper将采用分布式設計,并“基于标準的谷歌基礎設施建構,最初是Bigtable”),接下來的任務便是實際建立并實施這套新方案。待Piper部署完畢後,他們還需将所有流量切換到新系統,并遷移整個谷歌單一倉庫。
這一努力耗時超過四年之久。
乍看之下,這個時間跨度令人震驚,但在長達十一年的時間裡,Perforce已深深植根于谷歌的軟體生态系統之中,幾乎觸及每一個工程層面。
遷移開始時,已有300種工具依賴于Perforce的API。更為驚人的是,生産環境對于Perforce的依賴不斷浮現。理想情況下,版本控制系統應當嚴格面向内部,即使崩潰也不應影響實時流量;然而Piper團隊不斷發現情況并非如此。總體而言,執行遷移的工程師們必須極其謹慎,以免破壞谷歌終端使用者體驗。
事态進一步複雜化的是,在2010年,Oracle因谷歌在Android作業系統中使用授權Java API接口而對其提起訴訟。直到2021年,該案才由最高法院作出最終裁決。
在這段過渡期中,谷歌的工程師團隊深切憂慮着如何在不全面複刻原有接口的前提下,實作從Perforce API平滑過渡的難題。為了解決這一棘手挑戰,他們轉向了一個廣受業界推崇的創新政策——淨室設計(clean room design)方法。
這一方案首先由技術文檔撰寫者精心制定詳盡的規格說明,随後交由一群完全未接觸過原生API的獨立工程師團隊,他們猶如一張白紙,從零開始,依據這份純淨的設計藍圖,建構起全新的系統架構,確定了遷移過程的無縫銜接與原創性,巧妙規避了直接複制接口所帶來的潛在法律與技術風險。
随着時間推移,項目基調發生了變化。起初,Piper是一個新穎酷炫的概念,工程師們對此充滿熱情,它可能是解決Perforce問題的關鍵。然而,随着時間流逝,他們的工作變得日益緊迫。
在遷移過程中,谷歌的開發工作未曾停歇,幾年間,Perforce上的負載持續增加,風險随之升高。Perforce API上出現了大量新開發,包括如今舉足輕重的系統如Blaze(谷歌的建構系統,後開源為Bazel)和TAP(谷歌内部測試平台)。
這項決策之是以堪稱大膽且不同尋常,不僅僅因為它耗費了工程師團隊數年的辛勤規劃與投入,更在于其成果性質的極端兩極化——要麼圓滿達成,所有心血瞬間開花結果;要麼徹底落空,一切努力付諸東流,中途絕無半點折中收獲。
考慮到維護源代碼唯一權威版本的至關重要性,谷歌明白,除非Piper系統能全面替代現有方案,否則一切改進都将徒勞無功。Piper的命運掌握在成敗之間:要麼它将完美接棒,成為源代碼控制的全新中樞;要麼它将黯然退場,迫使谷歌重拾舊路,還将面對比以往更加艱巨的Perforce伺服器困境。
正因如此,當Piper項目組面臨實作PAXOS算法的關鍵時刻,他們果斷從Google Spanner團隊中借調了相關領域的專家,即便Spanner自身尚未完全掌握PAXOS的運用。這一舉動彰顯了谷歌内部資源共享與協同作戰的強大機制,關鍵時刻能夠跨部門調動頂尖人才,確定Piper項目順利推進。
随着遷移程序的深入,一個關鍵裡程碑得以實作——送出操作已能順暢地同步至Perforce與Piper雙系統,確定資料的無縫過渡。為了驗證新系統的穩健性,Piper團隊在特定區域内實施了小範圍的部署測試,效果令人鼓舞。
然而,真正的挑戰在于赢得25,000名谷歌工程師的心,引導他們跨越至Piper的嶄新時代。這不僅是一場技術上的革新,更是人心的征途。Piper團隊肩負重任,尤其是面對那些資深工程師,他們親自登門拜訪,耐心溝通,逐一化解疑慮,力求每一位同僚的了解與支援,進而掃清項目前行的最後障礙。
在某個平凡的周六,已擴充至十人的Piper項目核心團隊,齊聚于園區的會議室内。Jeff Dean,現任Alphabet的首席科學家,亦親臨現場,他的到來不僅是對項目進度的實地考察,更像一股強心劑,鼓舞着團隊士氣。
盡管Piper團隊早已進行了周密的準備,演練了無數遍,編寫了詳盡的腳本,安排了多重監控,并制定了詳實的應急指南,但内心深處的擔憂卻難以抹去——這十位工程師肩上的擔子,可能決定了谷歌的營運命運,一次不慎,或将引發不可預知的後果。
當遷移指令正式下達,短短幾分鐘内,源控制系統進入隻讀模式,一切仿佛凝固,隻為那一瞬間的資料遷移鋪平道路。會議室裡,衆人屏息靜待,空氣中彌漫着一種既期待又忐忑的情緒,每個人的心跳聲似乎都能清晰聽見,共同見證着曆史性的轉折點。
然後……遷移順利完成。
沒有資料丢失;谷歌的生産執行個體未受影響。
就這樣,曆時多年的孤注一擲獲得了回報。
塵埃落定:獨屬于谷歌的黃金年代
切換到Piper立即降低了谷歌的操作風險,擺脫了對單個過載Perforce伺服器的依賴。但随着時間推移,遷移也通過源控制伺服器現在支援的新流量規模解鎖了一系列新系統。
自2012年的遷移之後,自動化送出的數量開始激增。
在當今時代,提及谷歌的内部工具體系,人們往往會自然而然地将其與一家資源豐沛、實力雄厚的巨型公司聯系起來,想象中這是一家能夠在充裕的時間與空間裡,精心打磨出一系列前沿科技産品的巨無霸公司。
然而,追溯至2012年,谷歌從Perforce向Piper的遷移曆程,卻為我們揭開了一個截然不同的視角——彼時,正值谷歌上市後的第八個年頭,一個充滿創業激情與大膽創新精神的黃金年代。在這段歲月裡,谷歌展現出一股無畏挑戰、勇攀高峰的拼搏勁頭。Piper遷移項目的意義遠不止于技術層面的革新,它更深層次地折射出谷歌工程師文化的核心價值——創新、協作與追求卓越。
參考連結:
https://www.reddit.com/r/programming/comments/1dsf4z3/around_2013_googles_source_control_system_was/
https://graphite.dev/blog/google-perforce-to-piper-migration