天天看點

來自谷歌的開發心得:所有SQL和代碼,都沒必要藏着掖着

作者 | Galen B

翻譯 | 核子可樂

策劃 | Tina

至少從工程技術的角度看,你的項目絕沒有想象中那麼“見不得光”。

谷歌在代碼管理上很有特色,他們基于“主幹”進行開發,并且将 90% 以上的代碼放在名叫 Piper 的單一代碼倉庫中,由來自世界各國數十個辦事處的數萬名軟體開發人員共享。對于那些開源的、需要外部協作的項目,代碼才放在版本管理軟體 Git 裡,主要是 Android 項目和 Chrome 項目。

整個倉庫采用樹狀結構,每個團隊有自己的目錄,目錄路徑就是代碼的命名空間。每個目錄都有負責人(owner),負責準許該目錄的檔案變動。

這種方法已經在谷歌運作了 20 年以上。2015 年,谷歌的這個代碼庫就包含了大約十億個檔案,并且具有約 3500 萬次送出的曆史。代碼一般送出到主幹的頭部,保證所有使用者看到的都是同一份代碼的最新版本,支援檔案級别的權限控制,99% 的代碼對所有使用者可見。隻有少部分重要的配置檔案和機密的關鍵業務,設有通路限制。所有的讀寫都有日志,管理者能夠查到誰讀過這個檔案。

與給代碼制定各種通路權限的管理方式相比,谷歌的方法帶來的好處是很明顯的:任何人都可以浏覽和使用全公司的代碼,大大促進了代碼的共享和複用;具有統一的版本和路徑,不存在找不到檔案的最新版本這樣的問題;每次代碼變動,很容易撤銷或者用預送出測試它所造成的影響......

就連 SQL 的管理,谷歌也在一定程度上遵循了這些原則。本文作者是一名資料工程師,給谷歌當了兩年的供應商,在期間發現谷歌的資料工程師對待 SQL 的态度,跟軟體工程師們對待代碼的态度非常相似。他認為這種态度非常重要,無論大小企業都值得在資料戰略中采取這樣的心态。我們将作者的文章翻譯了出來,通過他的文章,我們将一同了解谷歌這種把 SQL 當成代碼的态度有哪些助益,又能給體量較小的組織機構帶來哪些啟示。

1

SQL 隻是種查詢語言,谷歌為什麼要把它看作代碼?

跟面向對象代碼一樣,SQL 編寫起來也相當耗時、調試難度不低、内容難以了解(不利于版本控制),而且高度強調可維護性。單從谷歌資料工程部門自身的情況來講,SQL 完全可以用來建立資料管道,而資料管道又特别強調易調試、易修複。考慮到這些因素,代碼集中度越高、資料戰略的落地實踐才能越順暢。

是以把 SQL 看作代碼,意味着我們可以把代碼管理工具引入流程,輕松了解由誰負責特定變更或者維護 SQL 腳本、并持續跟蹤同一作者在其他相關查詢中的調整。如此一來,我們就能快速找到失敗送出,恢複變更内容或者應用必要修複。在送出 SQL 代碼之後,這部分代碼可以被立即部署到開發環境當中。接下來就是運作開發管道,即時識别并修複故障。

另外,我們還會定期釋出測試環境,通過更新保證代碼能在生産版本上跑通。在測試成功之後,新舊兩個生産版本之間送出的 SQL 代碼才能正式啟用,把出問題的幾率控制在最低水準。

小公司該學習什麼?

審視自己的軟體工程文化,把谷歌這種更為成熟的文化理念設為标杆,體會并試用他們選擇的工具,包括 Git、IDE 等。我們應該把所有代碼都明确列入索引位置,花點時間将專用腳本轉化成全局腳本,消除視圖、物化視圖、存儲過程等一切不必要的元素。

2

谷歌是怎麼管理 SQL 代碼的?

谷歌把幾乎所有代碼都放在統一的集中代碼存儲庫裡。是以在需要對 SQL 做出變更時,或者需要建立新的腳本時,谷歌的工程師就建立一份相應的變更清單——在本質上類似于 PR。之後,變更流程需要接受測試并由其他工程師負責核準。核準順利通過,作者才可以把代碼變更送出至代碼存儲庫。

雖然這種變更控制形式在企業中相當常見,但谷歌的一大特色在于高度強調代碼格式的重要性。我本人以往對代碼格式不太重視,但切身經曆讓我意識到高品質的代碼格式确實能大大降低了解和調試難度、也有助于縮短其他作者在代碼修改上耗費的時間。谷歌特别重視代碼格式,甚至設立了一套自動化機制、直接拒收不符合編碼标準的代碼。

選擇一套代碼存儲庫,然後堅持以它為中心開展後續工作。在理想情況下,這套存儲庫應該在各工程團隊間共享,至少也得保證把所有 SQL 代碼集中進來。其中應該涵蓋全部資料功能,包括資料工程、分析、商務智能等等。

另外,一定要推行代碼格式标準化。目前市面上有不少開源代碼格式标準化工具,它們使用難度不高,而且能極大提升代碼的可讀性與可維護性。花點時間,使用現有格式化工具或者内部的原研工具把原有代碼梳理一遍,同時保證後續送出的一切代碼都必須符合格式标準。幾天、最多幾個禮拜,資料工程師們就能适應這套新的标準,并讓公司内的 SQL 代碼在可讀性、編寫品質和可了解性方面都上一個台階。

3

版本控制 + 多種測試環境 = 節約時間

代碼變更無處不在,如果沒有版本控制加以限制,我們将很難用復原來補救意外錯誤。萬一送出的代碼破壞了管道、産生了預期之外的值或者跑不通,那我們就得利用版本控制恢複至上一個正常狀态。

谷歌的代碼內建原則也遵循這樣的思路。哪怕變更内容再離譜(真的,有時候送出的代碼就是這麼離譜),擁有良好結構的測試環境也能從容消化,不緻對正常業務造成幹擾。如此一來,SQL 變更對于開發環境的影響就能直接展現,幫助工程師們快速發現故障。

當然,也有極少數代碼在開發環境中不會立即造成故障,但在生産環境裡卻問題頻發。造成這種狀況的因素多種多樣,是以我們需要在測試體系中引入單獨的預生産環境。

谷歌使用環境變量來管理多種測試環境,這些變量可以通過解釋層被輕松注入至表名當中。

至少要建立一套開發環境,同時盡可能擴大代碼測試所涉及的資料基礎設施範圍,這樣才能把出現故障的幾率降至最低。DBT 等免費開源工具就通過抽象層顯著降低了測試難度,其中所有表都有兩個版本,一個是開發版、一個是生産版。這樣在每日、每周乃至每月的釋出計劃中,我們就能安心把上次釋出計劃之後送出的所有代碼都直接提升至生産環境。

4

廣泛的代碼通路能力

正所謂“成也蕭何、敗也蕭何”,谷歌把幾乎所有代碼塞進單一代碼存儲庫的作法,導緻我們很難厘清某一産品究竟歸誰所有、又有哪些人在使用。例如,如果不能廣泛通路這套集中代碼庫,軟體工程師在更新生産級應用程式時就很難了解變更會引發哪些下遊影響。而在獲得廣泛通路能力後,他們可以輕松搜尋到對目前應用程式構成依賴的腳本、查詢操作及其他應用程式,并通知相應工程師開展變更協同。

我知道,很多企業總想用代碼保密的方式把不同開發環節隔離開來。沒錯,某些高度敏感的項目代碼庫确實不該随意開放,但這類項目不多、而且跟其他項目間的聯系也不會太緊密。既然谷歌這樣規模龐大的企業巨頭,在建立代碼架構時都願意充分發揮信任的力量,那其他小公司真的沒必要總是藏着掖着。

在代碼庫和存儲庫的結構設計中多多引入信任與溝通機制。至少從工程技術的角度看,你的項目絕沒有想象中那麼“見不得光”。畢竟如果你連團隊中的工程師都不能信任,那這家企業還能正常營運嗎?總之,請主動在業務流程中的軟體工程與資料工程之間打通邊界、鼓勵協作。也隻有這樣,我們才能在代碼在生産環境中落地之前,搶先一步解決由變更引發的負面下遊影響。

繼續閱讀