avatarvgod's blog

总结

网页探讨了軟體工程師在大型公司中面临的规模和复杂度挑战。

摘要

网页内容描述了軟體工程師在大型公司中面临的规模和复杂度挑战。随着公司的扩大,程序库的规模和复杂度也会随之增加,这会给新入职的工程师带来困难。例如,Google在2015年公布,他们当时有25000个工程师,总共已经累積20亿行程式码,而且全都在同一个程式库里。这种规模的复杂度对于工程师来说是一种技术挑战,但也是阻碍公司发展的障碍。

观点

  1. 随着公司的扩大,程序库的规模和复杂度也会随之增加。
  2. 在大型公司中,新入职的工程师面临着了解现有系统和找到从哪里开始的挑战。
  3. 大型公司需要雇用大量工程师来处理规模和复杂度的问题。
  4. 大型公司需要有專門的團隊負責建造和维护基础建设和平台。
  5. 随着使用者的增加,系统的复杂度也会指数级增加。
  6. 大规模的复杂度对于工程师来说是一种技术挑战,但也是阻碍公司发展的障碍。
  7. 新創公司动得快,但大公司有太多现有的包袱需要顾虑,规模越大就越难做大范围的改动。

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

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 source軟體或是AWS之類的雲端平台,但總還是要有人負責決定用哪個系統,然後要怎麼跟公司內的其他系統接上去。這個導入和遷移過程都要花上好一段時間,即使完成了也要持續維護和升級,並不是說只要用了AWS,公司就不需要有做基礎建設或是平台的團隊了。

當使用者長到千萬甚至上億的等級時,很多現有的open source系統(像是MySQL這種常見的資料庫)或是基本的AWS功能也會開始不堪用了。公司內負責這些領域的團隊就得找來更高等級的工程師,在這些系統之上做最佳化,把資料用對的方式切割開來儲存和處理,想辦法利用現有的系統能容納更多使用者的需求。這些事情也不是說要做馬上就能做好的,要保持現有系統正常運作,又要開發和遷移到新系統,常常都得要一整個團隊做上一兩年才行。到最後,世界上已經沒有現成的系統可以滿足公司的需求了,公司只好開始發明自己的新系統,更好的資料庫、更好的資料儲存格式、更好的前後端開發框架、更好的編譯工具…。每一個這樣的系統都得找一群頂尖的工程師來開發和遷移才行。

就這樣,一個小網站為了應付使用者的增加,除了使用者看得到的那個網頁和apps外,後面所有的系統和工具都得一直跟著成長。這些團隊,小的可能4、5個人,大一點的可能十多人,在大規模的公司裡會有幾百個甚至幾千個,這也是為什麼大型科技公司會有這麼多工程師。一但使用者變多,每一件原本看來很小的事都會指數級變難,系統的複雜度也就跟著指數級升高。因為系統變複雜了,改變現有系統的難度和風險也變得很高。如果系統沒設計好或是沒有足夠的防護措施,有時候一個小錯誤可能就會讓整個產品都掛掉。(還記得去年10月Facebook大當機嗎?)

這種指數增加的複雜度對工程師來說是一種很好的技術挑戰,因為世界上沒多少公司需要處理這種規模的問題。但另一方面,這些複雜度也是阻礙公司繼續創新和發展的惡魔。這也是為什麼新創公司都能夠動得很快,但大公司有太多現有的包袱(收入、合作夥伴、使用者、產品、系統、工具、團隊、股東…)需要顧慮,規模越大就越難做大範圍的改動。

(待續)

軟體工程師的修煉與成長
Software Engineering
Recommended from ReadMedium