軟體工程師的修煉與成長 (2) — 規模與複雜度
規模與複雜度
上集聊到軟體工程是「團隊接力馬拉松」,越大的公司就有越多人累積越多時間和程式碼在公司的程式庫上。對於剛畢業的L3工程師來說,要在加入一個已經有規模的公司後馬上開始有貢獻,最難的往往不是把自己被交代的任務寫出來這部分,而是在了解現有系統是如何運作並且找到該從哪裡下手開始。一個稍微有規模的公司,整個程式庫常常有十年以上的歷史,經過幾百人甚至幾千人的修改是很常見的事。如果是Google、Facebook、Microsoft、Amazon這種有上萬人接力二三十年的公司,程式庫的規模更是大得驚人,公司裡不管多資深或多高層的人都沒辦法瞭解全貌。
Google就曾在2015年公布過,他們當時有2萬5千個工程師,總共已經累積20億行程式碼,而且全都在同一個程式庫裡。不是軟體工程師可能很難理解,為什麼很多公司看起來就是一個網站而已,為什麼需要雇用這麼多工程師寫這麼多程式?很多學生專案可能就是「複製一個Facebook」或是「複製一個Youtube」,看起來一個學生花一學期就能做到了,這些公司有幾萬個工程師到底在幹嘛?
一個學生做的「Facebook複製品」和真正的Facebook最大的差異在哪?其實就是「規模」兩個字。
一個學生網站用現成的open source系統拼接起來,通常也就在期末demo時可以「自己一個人」操作一下,證明基本功能都能運作就結束了。好一點的專案可能還會真的放上線給同學們用,使用者就開始增加,可能到10人或20人。這時應該還不是大問題,因為這十幾個人很少會同時間使用,所以在不同時間點看,同時間的使用者其實還是一個人。
但如果真的有人在用,時間一長累積的資料就會變多,系統的短處就會開始暴露出來。例如說,小專案的資料庫都沒有適當的索引,在資料量小時不會感覺到有什麼問題。但當系統累積的文章變多,就會發現每次取出文章列表時就得要掃過整個資料庫。隨著累積的文章越多,這個列表速度就越慢。隨著使用者變多,這個問題也會跟著變糟。
如果使用者再變多一點,到了幾百幾千人的規模,同時上線的人數也會變多。這時網站平常就不再是同時只有一個人在使用的狀態了,如果程式沒設計好,同時有多人在讀寫資料很容易就會造成race condition,像是有些資料莫名的消失或是被覆寫之類的問題就可能會一直跑出來。
這些問題都還是在考驗設計者的技術能力,一個網站能不能規模化的第一個技術瓶頸就在於能不能正確處理這些問題。假設這些問題都被正確的處理掉了,網站也很受歡迎,使用者繼續增加到幾萬人,很快地就會遇到單一台機器的瓶頸。一台機器能服務的使用者是很有限的,這時就得開始把整個系統拆開變成幾個分開的零組件,像是把資料庫分出去變成單獨的伺服器,或是把前端的頁面都放到CDN去,把後端的API伺服器也獨立出去。
麻煩的是,這些事情已經不像以前那麼好做了。當網站沒人用時,隨時都可以關掉,把想做的改變做一做,重新上線就好了。但現在網站隨時都有使用者在線上,關掉幾個小時都會讓使用…