點擊下方卡片,關注「新機器視覺」公眾號
視覺/圖像重磅乾貨,第一時間送達
谷歌在代碼管理上很有特色,他們基於「主幹」進行開發,並且將 90% 以上的代碼放在名叫 Piper 的單一代碼倉庫中,由來自世界各國數十個辦事處的數萬名軟件開發人員共享。對於那些開源的、需要外部協作的項目,代碼才放在版本管理軟件 Git 里,主要是 Android 項目和 Chrome 項目。
整個倉庫採用樹狀結構,每個團隊有自己的目錄,目錄路徑就是代碼的命名空間。每個目錄都有負責人(owner),負責批准該目錄的文件變動。
這種方法已經在谷歌運行了 20 年以上。2015 年,谷歌的這個代碼庫就包含了大約十億個文件,並且具有約 3500 萬次提交的歷史。代碼一般提交到主幹的頭部,保證所有用戶看到的都是同一份代碼的最新版本,支持文件級別的權限控制,99% 的代碼對所有用戶可見。只有少部分重要的配置文件和機密的關鍵業務,設有訪問限制。所有的讀寫都有日誌,管理員能夠查到誰讀過這個文件。
與給代碼制定各種訪問權限的管理方式相比,谷歌的方法帶來的好處是很明顯的:任何人都可以瀏覽和使用全公司的代碼,大大促進了代碼的共享和復用;具有統一的版本和路徑,不存在找不到文件的最新版本這樣的問題;每次代碼變動,很容易撤銷或者用預提交測試它所造成的影響......
就連 SQL 的管理,谷歌也在一定程度上遵循了這些原則。本文作者是一名數據工程師,給谷歌當了兩年的供應商,在期間發現谷歌的數據工程師對待 SQL 的態度,跟軟件工程師們對待代碼的態度非常相似。他認為這種態度非常重要,無論大小企業都值得在數據戰略中採取這樣的心態。我們將作者的文章翻譯了出來,通過他的文章,我們將一同了解谷歌這種把 SQL 當成代碼的態度有哪些助益,又能給體量較小的組織機構帶來哪些啟示。
跟面向對象代碼一樣,SQL 編寫起來也相當耗時、調試難度不低、內容難以理解(不利於版本控制),而且高度強調可維護性。單從谷歌數據工程部門自身的情況來講,SQL 完全可以用來創建數據管道,而數據管道又特別強調易調試、易修復。考慮到這些因素,代碼集中度越高、數據戰略的落地實踐才能越順暢。
所以把 SQL 看作代碼,意味着我們可以把代碼管理工具引入流程,輕鬆了解由誰負責特定變更或者維護 SQL 腳本、並持續跟蹤同一作者在其他相關查詢中的調整。如此一來,我們就能快速找到失敗提交,恢復變更內容或者應用必要修復。在提交 SQL 代碼之後,這部分代碼可以被立即部署到開發環境當中。接下來就是運行開發管道,即時識別並修復故障。
另外,我們還會定期發布測試環境,通過升級保證代碼能在生產版本上跑通。在測試成功之後,新舊兩個生產版本之間提交的 SQL 代碼才能正式啟用,把出問題的幾率控制在最低水平。
審視自己的軟件工程文化,把谷歌這種更為成熟的文化理念設為標杆,體會並試用他們選擇的工具,包括 Git、IDE 等。我們應該把所有代碼都明確列入索引位置,花點時間將專用腳本轉化成全局腳本,消除視圖、物化視圖、存儲過程等一切不必要的元素。
谷歌把幾乎所有代碼都放在統一的集中代碼存儲庫里。所以在需要對 SQL 做出變更時,或者需要創建新的腳本時,谷歌的工程師就建立一份相應的變更清單——在本質上類似於 PR。之後,變更流程需要接受測試並由其他工程師負責核准。核准順利通過,作者才可以把代碼變更提交至代碼存儲庫。
雖然這種變更控制形式在企業中相當常見,但谷歌的一大特色在於高度強調代碼格式的重要性。我本人以往對代碼格式不太重視,但切身經歷讓我意識到高質量的代碼格式確實能大大降低理解和調試難度、也有助於縮短其他作者在代碼修改上耗費的時間。谷歌特別重視代碼格式,甚至設立了一套自動化機制、直接拒收不符合編碼標準的代碼。
選擇一套代碼存儲庫,然後堅持以它為中心開展後續工作。在理想情況下,這套存儲庫應該在各工程團隊間共享,至少也得保證把所有 SQL 代碼集中進來。其中應該涵蓋全部數據功能,包括數據工程、分析、商務智能等等。
另外,一定要推行代碼格式標準化。目前市面上有不少開源代碼格式標準化工具,它們使用難度不高,而且能極大提升代碼的可讀性與可維護性。花點時間,使用現有格式化工具或者內部的原研工具把原有代碼梳理一遍,同時保證後續提交的一切代碼都必須符合格式標準。幾天、最多幾個禮拜,數據工程師們就能適應這套新的標準,並讓公司內的 SQL 代碼在可讀性、編寫質量和可理解性方面都上一個台階。
代碼變更無處不在,如果沒有版本控制加以約束,我們將很難用回滾來補救意外錯誤。萬一提交的代碼破壞了管道、產生了預期之外的值或者跑不通,那我們就得利用版本控制恢復至上一個正常狀態。
谷歌的代碼集成原則也遵循這樣的思路。哪怕變更內容再離譜(真的,有時候提交的代碼就是這麼離譜),擁有良好結構的測試環境也能從容消化,不致對正常業務造成干擾。如此一來,SQL 變更對於開發環境的影響就能直接體現,幫助工程師們快速發現故障。
當然,也有極少數代碼在開發環境中不會立即造成故障,但在生產環境裡卻問題頻發。造成這種狀況的因素多種多樣,所以我們需要在測試體系中引入單獨的預生產環境。
谷歌使用環境變量來管理多種測試環境,這些變量可以通過解釋層被輕鬆注入至表名當中。
至少要建立一套開發環境,同時儘可能擴大代碼測試所涉及的數據基礎設施範圍,這樣才能把出現故障的幾率降至最低。DBT 等免費開源工具就通過抽象層顯著降低了測試難度,其中所有表都有兩個版本,一個是開發版、一個是生產版。這樣在每日、每周乃至每月的發布計劃中,我們就能安心把上次發布計劃之後提交的所有代碼都直接提升至生產環境。
正所謂「成也蕭何、敗也蕭何」,谷歌把幾乎所有代碼塞進單一代碼存儲庫的作法,導致我們很難分清某一產品究竟歸誰所有、又有哪些人在使用。例如,如果不能廣泛訪問這套集中代碼庫,軟件工程師在更新生產級應用程序時就很難理解變更會引發哪些下游影響。而在獲得廣泛訪問能力後,他們可以輕鬆搜索到對當前應用程序構成依賴的腳本、查詢操作及其他應用程序,並通知相應工程師開展變更協同。
我知道,很多企業總想用代碼保密的方式把不同開發環節隔離開來。沒錯,某些高度敏感的項目代碼庫確實不該隨意開放,但這類項目不多、而且跟其他項目間的聯繫也不會太緊密。既然谷歌這樣規模龐大的企業巨頭,在建立代碼架構時都願意充分發揮信任的力量,那其他小公司真的沒必要總是藏着掖着。
在代碼庫和存儲庫的結構設計中多多引入信任與溝通機制。至少從工程技術的角度看,你的項目絕沒有想象中那麼「見不得光」。畢竟如果你連團隊中的工程師都不能信任,那這家企業還能正常運營嗎?總之,請主動在業務流程中的軟件工程與數據工程之間打通邊界、鼓勵協作。也只有這樣,我們才能在代碼在生產環境中落地之前,搶先一步解決由變更引發的負面下游影響。
原文鏈接:
https://blog.devgenius.io/why-google-treats-sql-like-code-and-you-should-too-53f97925037e
本文僅做學術分享,如有侵權,請聯繫刪文。
