軟體工程師的修煉與成長 (2) — 規模與複雜度

vgod's blog
Feb 14, 2022
Source: nerovivo via Flickr (CC BY 2.0)

規模與複雜度

上集聊到軟體工程是「團隊接力馬拉松」,越大的公司就有越多人累積越多時間和程式碼在公司的程式庫上。對於剛畢業的L3工程師來說,要在加入一個已經有規模的公司後馬上開始有貢獻,最難的往往不是把自己被交代的任務寫出來這部分,而是在了解現有系統是如何運作並且找到該從哪裡下手開始。一個稍微有規模的公司,整個程式庫常常有十年以上的歷史,經過幾百人甚至幾千人的修改是很常見的事。如果是Google、Facebook、Microsoft、Amazon這種有上萬人接力二三十年的公司,程式庫的規模更是大得驚人,公司裡不管多資深或多高層的人都沒辦法瞭解全貌。

Google就曾在2015年公布過,他們當時有2萬5千個工程師,總共已經累積20億行程式碼,而且全都在同一個程式庫裡。不是軟體工程師可能很難理解,為什麼很多公司看起來就是一個網站而已,為什麼需要雇用這麼多工程師寫這麼多程式?很多學生專案可能就是「複製一個Facebook」或是「複製一個Youtube」,看起來一個學生花一學期就能做到了,這些公司有幾萬個工程師到底在幹嘛?

一個學生做的「Facebook複製品」和真正的Facebook最大的差異在哪?其實就是「規模」兩個字。

一個學生網站用現成的open source系統拼接起來,通常也就在期末demo時可以「自己一個人」操作一下,證明基本功能都能運作就結束了。好一點的專案可能還會真的放上線給同學們用,使用者就開始增加,可能到10人或20人。這時應該還不是大問題,因為這十幾個人很少會同時間使用,所以在不同時間點看,同時間的使用者其實還是一個人。

但如果真的有人在用,時間一長累積的資料就會變多,系統的短處就會開始暴露出來。例如說,小專案的資料庫都沒有適當的索引,在資料量小時不會感覺到有什麼問題。但當系統累積的文章變多,就會發現每次取出文章列表時就得要掃過整個資料庫。隨著累積的文章越多,這個列表速度就越慢。隨著使用者變多,這個問題也會跟著變糟。

如果使用者再變多一點,到了幾百幾千人的規模,同時上線的人數也會變多。這時網站平常就不再是同時只有一個人在使用的狀態了,如果程式沒設計好,同時有多人在讀寫資料很容易就會造成race condition,像是有些資料莫名的消失或是被覆寫之類的問題就可能會一直跑出來。

這些問題都還是在考驗設計者的技術能力,一個網站能不能規模化的第一個技術瓶頸就在於能不能正確處理這些問題。假設這些問題都被正確的處理掉了,網站也很受歡迎,使用者繼續增加到幾萬人,很快地就會遇到單一台機器的瓶頸。一台機器能服務的使用者是很有限的,這時就得開始把整個系統拆開變成幾個分開的零組件,像是把資料庫分出去變成單獨的伺服器,或是把前端的頁面都放到CDN去,把後端的API伺服器也獨立出去。

麻煩的是,這些事情已經不像以前那麼好做了。當網站沒人用時,隨時都可以關掉,把想做的改變做一做,重新上線就好了。但現在網站隨時都有使用者在線上,關掉幾個小時都會讓使用者不爽而流失。於是,本來關掉網站不用一天就能做好的遷移,現在得小心翼翼地進行,讓網站在維持100%上線的情況下把後面資料搬家或是把零件偷偷換掉。這個遷移過程比以前麻煩多了,本來幾個小時的工作一下就變成了好幾天甚至幾個星期。

網站繼續長大,很多功能就變得越來越慢,整個網站也越來越不穩定。網站的創辦人很快就意識到事情已經太多了,他自己一個人做不來,光應付成長帶來的問題時間都不夠了,更何況增加新功能。他得找更多工程師來才行。於是他開始找團隊,一個團隊負責一兩個產品功能,讓這些功能變得夠快夠穩外,還要持續加新功能。此外,網站變大也變成駭客的攻擊目標,也得找人加強安全防護,以前亂寫的使用者登入和儲存在資料庫的明碼密碼都變成了要解決的問題。使用者除了網站外也想要在手機上用,好吧,那就找人寫iOS和Android apps。

於是這個創辦人花了很多時間雇用和面試新人,後來甚至要僱用專門負責招募的團隊來雇人。同時因為雇用的新人太多,所以也要有團隊專門開課程寫教材訓練這些新人。顧太多人花很多錢,同時還得募資,還有開始加上能讓網站賺錢的廣告系統,這樣又要雇用更多人來寫這些系統….。

隨著使用者慢慢增加,團隊也這樣慢慢長大。每個產品功能都被切得更細,每個小功能都有一個專門負責的團隊在做,每個pixel都要有人精心設計過。而為了讓這些產品團隊專心做產品,很多共通的底層系統和基礎建設,像是常見的各種資料庫(SQL、key value store、document store等等)、非同步的任務處理系統 、分散式的計算平台、分析記錄使用者活動的資料管線和倉儲、監看系統狀況的儀表板和警報都開始「平台化」。不但有專門的團隊負責建造這些平台,他們還會做成能讓公司內不同產品功能都能通用的樣子。到後來,像是給工程師用的部署工具、機器管理工具、程式碼管理工具、測試工具、編譯工具、code review工具等等全都有各自的團隊負責。

這些東西雖然很多都有現成的open…

--

--