關於大規模網際網路系統開發運維和組織管理的總結(2016-11)

支 持 本 站: 捐贈伺服器等運維費用,需要您的支持!

通過某次交流,把自己對大型網際網路系統設計開發運維以及部門管理時的實踐思路簡單總結一下。
為了保密這裡不涉及具體的項目名,硬體,OS,語言,軟體和資料庫選型,
另外每個項目的團隊經驗和企業業務邏輯千變萬化,所以也只從一些抽象的概念上進行小結。

在網際網路產業工作了近20年,尤其是從2000年起一直在這個網站工作,
公司規模以工程師人數來說,從當時只有三十多名發展到現在的二三千名,
以startup的心態加入公司,當時實在是沒想到會發展到如此的規模。
另外訪問量也從每天的幾千萬PV到幾十億PV,加上API以及各種靜態資源,
雖然沒有具體的統計數字,但是每天上百億的訪問肯定是有的。
自己也從devops開始做起,到多項目的架構設計,
以及項目和部門的宏觀管理,還是能感到業務經驗和知識的成長的。

自己的想法可以從下面幾個軸來考慮
--資訊安全,軟體工程,構架,團隊建設,宏觀管理。

一是資訊安全的三要素CIA,機密性Confidentiality,完整性Integrity,可用性Availability,
別管系統的規模有多大,用戶數有多少,技術多麼先進,
有安全性隱患的東西誰都不敢用的,
因此資訊安全的這三點是系統設計和業務設計最基本的原則。

這麼多年來,經歷過DoS攻擊,ATP攻擊,
內部人員盜竊客戶數據,設計不當的大規模當機等大事件,
因此對安全性的感受頗深。

資訊安全工作具體包括:
通過軟硬體的訪問控制設計使所需資訊只能由最少的人能接觸到;
通過加密使重要數據不會泄漏和盜取;
通過對平均故障恢復時間MTTR,單一故障點等主要KPI持續收集並不斷評價;
通過建立資訊安全事件管理體制和預備計劃,這樣在Incident發生時就不會手足無措;
通過風險管理不斷找出系統和業務中的不確定性要素,並不斷加以改進;
通過建立CSIRT和Security Operation Center組織不斷收集對內對外系統的脆弱性資訊,並不斷升級等等。

ISO 27001的ISMS資訊安全管理系統對此有個比較概括的定義,
資訊系統安全認證專家CISSP裡面有更多的實踐性的描述。
參加過ISMS和CISSP的培訓,覺得裡面的總結還是非常全面的,
(公司不斷提供這種外部培訓, 花了都有100萬日元了吧)
因此在工作中會有意識地應用這些原則。

二是軟體工程Software Engineering的一些基本原則的貫徹。
自己在大學裡學習的是電子工程,不是計算機科學,因此對於算法等領域不精通,
在工作中往往需要這方面的專家來解決問題,
比如以前(2008年到2010年的一個項目)曾和美國方面的科學家們建立機器學習的模型。
但是作為工程師,如何把模型真正的反映到系統里去,理論聯繫實踐,
既需要一般計算機系統的開發,
更需要不斷調試參數,不斷更新擴大字典和知識庫的過程。

因此作為工程人員,在有限的人力物力資源情況下,
為了完成經營者要求的業務目標和日程表,
需求管理,架構設計,工程進度和人員資源管理,開發流程和規範制定,
質量管理,維護管理等實踐性知識和經驗就非常重要。
當然長遠的規劃,方向性技術選型,配合經營方針對組織結構的調整,
這些也都是軟體工程中的重要內容。

最近的項目里,
使用靈活的Scrum敏捷開發項目管理;
使用面向對象的軟體設計和系統設計;
使用Restful的WebAPI和SOA對功能進行服務化和解耦;
使用CI/CD把以往需要手工做的版本管理/測試/編譯/連結/部署等一系列工作自動化;
這些都已經成為理所當然的選擇。



支 持 本 站: 捐贈伺服器等運維費用,需要您的支持!

第三是關於系統架構,因為是網站,最一開始IDC數據中心的問題要解決。
當然中小型網站,使用亞馬遜/谷歌/微軟/百度/阿里提供的雲服務是最省事的方法,
但是這裡的前提是大規模網站,如果用雲服務也不是不可以,
從經濟性來說還是自己搭網站比較划算吧。
因此數據中心選擇時,安全性,有線電視監視系統,可擴展性,
365天24小時的故障對應體制,發電設備,UPS電池的老化管理等等都成為考慮因素。

十幾年前的話晚上有系統故障,如果又不能遠程登錄上伺服器,
即使半夜三四點鐘也只好打車到數據中心,接上鍵盤顯示器拿console做維護;
有時還要自己去把有問題的伺服器從機櫃搬出並換上備用機器;
現在好多了,有VPN也有了搞IDC的子公司,很多問題即使相隔幾百公里,一個電話就可以解決。

從商業計劃中預測的用戶數/訪問量/交易量等算出幾年後需要的網絡帶寬,
因此可以購買合適的路由器,負載平衡,交換機,防火牆等設備。
網絡出口當然很重要,但是往往系統內部的流量要遠遠大於外部,
比如前台/多層分布式業務層/緩存/分布式資料庫/監控/數據分析/內部業務系統工具等子系統之間的通信量極其巨大,
用於內部的網絡設備的帶寬絕對不能忽視。

BCP也是需要的,尤其是在地震多發的日本地區,
在北部/中部/南部建立多個IDC也成為當前的常識。
colo之間的網絡延遲確實是個問題,這只能通過調整業務流程,
畢竟異步處理和數據一致性是很難兩全的。
另外根據物理位置路由到相關的colo,
儘可能減少跨IDC通信,做到"服務的本地化"也是提高處理速度的重要原則。

接下來是軟體構架。
子系統之間的stateless原則早在90年代初就已經由Roy Fielding提出來並用於http的設計。
REST(Representational State Transfer)的概念很多人不了解其詳細,
其實可以說這就是一個面向全球網絡級規模系統的設計規範。
我在公司寫WebAPI開發規範,七八年前給工程師們做SOA和REST講座的時候,
由於其內容太枯燥感覺一半人都睡著了。
但是REST中無狀態,緩存,面向資源,分層系統,統一接口以及多種方式資源的表現形式
等基本原則還是比較容易被應用於實際設計工作的。

現如今已經進入移動設備時代,為了開發手機應用APP,
工程人員和企劃人員對於產品"接口服務化"的認知度比起以往已經大大提高,
回想起十年多前在公司內推廣時的艱辛,有恍如隔世之感。

edge層或者網關層對於系統安全性的意義自然很重要,
OAuth用戶認證,TLS,路由,日誌,緩存,訪問控制等功能都可以由這一層來負責。
(在大約2007年的時候就在公司里提出WebAPI Gateway的構想,
但是因為工作調動沒有能把這個項目徹底推動下去,
今天夏天看到亞馬遜在AWS上推出了同名的服務,
看起來他們也是注意到了同樣的需求)
Circuit-breaker斷路器,Fail-fast,Retry,Throttling流控等技術術語最近經常看到,
我在08年的一個項目就實現了類似的功能,並和兩個部下一起還申請了專利,
不過確實人家起的名字就是很酷。

CDN對於靜態內容傳輸起到的高性能和可擴展性作用也是極其明顯的,這也是常識性知識了。

為了解決C10K問題,開發應用時也要注重對於系統資源的利用和tuning,
比如調整OS和伺服器軟體(如apache, mysql等)中網絡/內存/handler/緩衝/文件句柄的大小,
在經驗中即使是如apache1.x這種prefork+阻塞模式下也能很好的運作。
利用epoll/kqueue/libevent/nodejs的libev的多路復用技術已經非常成熟,
但非阻塞I/O模式下不考慮運維時對系統資源的監控也是不可想像的。

對於大規模系統來說,功能複雜,開發人員總多,
通過對"業務分層"把複雜的計算分開到專用層中,
能夠得到提高開發效率,對資源(CPU/存儲)有效分散後資源爭奪的瓶頸即會自然消解,
這一實踐也是從2000年就已經開始。
有時業務需要增加一些集中式狀態管理數據用來解決一致性問題,
但是很多情況下一致性問題並不會成為Web系統的瓶頸,
用戶很難感覺到這種短時間內的數據同步延遲。
至少自己負責的項目里,弱最終一致性的系統相對比較多。

對於大量數據,通過按照用戶維度分區sharding(shared nothing architecture)把數據分割,
在水平方向上可以做到無限拆分,高彈性伸縮的這種手法現在已經成為常識。
自己從2000年起在一些項目里就已經採用這種方法來搭建系統。
用戶數不會無限制增長,一般來說分拆數也是可以預測的,
因此動態分區的需求不會太高,雖然以前也用過動態hash環的做過實驗,
但是在實際系統中並沒有用上。

即使使用了分布式NoSQL資料庫,在一些業務需求下為了提高響應時間,
能夠做到帶狀態帶數據的分布式系統成為必須條件,
分層分區後每個子系統就變成一個矩陣的一個單元。
對數據訪問的路徑明確,所需要的數據可以通過最短路徑得到,
這樣的系統非常理想,但是運維可能會比較麻煩,
數據的備份和複製如果能夠以非常透明的方式實現,
那麼系統部署就會非常容易。
自己以前做過的項目中還使用的是手工操作管理,
支付寶單元化的智能方式還差的比較遠。
如果有非常清晰PaaS和IaaS的分層業務支持的話,
負責應用層開發的工程師就可以專注於產品業務邏輯,
開發和部署的速度都會大大改善,從這點上還是挺羨慕支付寶的平台的。

知道命令查詢職責分離模式CQRS(Command Query Responsibility Segregation)這個詞還是最近,
雖然從2000年起我們就使用這個方法做到NoSQL資料庫的讀寫分離,
通過異步消息隊列達到避免資源競爭。
CAP和BASE原則這些名詞也是很久之後才知道的,
但是使用事件模式,使用消息模式的實踐這麼多年來起就沒有停止過。

分布式事務的狀態管理有時需要引進一個集中式管理機制,這在上面也提到過了。
另外這種模式對於failover也很有幫助,數據複製非常容易實現。
還有大數據分析時通過消息隊列/消息總線可以很容易傳輸到hadoop一類的平台上。

軟體開發的方向應該就是不斷的抽象化,不斷的自動化,
通過高級語言,面向對象設計,面向對象編程,UML,服務化(IaaS, PaaS, BaaS, SaaS, FaaS...), 雲計算, CI/CD, 容器化,微服務等一系列技術演化,
今後DevOps工程師的工作可能會更趨向於建模和自動部署配置, 最終走上NoOps的方向,
像我們以往學習OS kernel的內部運作,大量UNIX命令和選項,讀apache等伺服器開源軟體源程序等需求會越來越少吧。

摩爾定律據說還要10年就會失效,
因此我們近幾十年來借硬體飛速升級得到的免費紅利會逐漸消失,
不深入考慮CPU/內存/IO也能做出大規模系統的好日子也許不會再來。
今後充分發揮計算機科學和軟體工程的力量,
對算法和並行計算模式研究的重要性會逐漸顯現出來。

第四是關於團隊建設的問題,
高水平團隊成員需要一個能夠自我管理,自我發展,以及能夠開放交流溝通的氛圍。
從最近參加的組織發展(Organization Development,OD)培訓里學到的干預技術也很有幫助。

從管理者的角度來說,這個open的團隊氛圍最為重要,
大家注重協調,自由發言,對事不對人,不搞官僚主義,
不用擔心有不同意見後的挑撥是非,
不用擔心秋後算帳的危險,讓團隊中所有人都擁有安心和安全感,
而不僅僅是一兩個嗓門大的人總在發言。

具體到實踐上,包括
更關注人的優點,不帶偏見,不帶有色眼鏡,寬容;
不浮躁,關注細節;
不急於得到結論,更關注課題的本質;
為了不迷失目標定期檢查和再定位,因為把手段當做目的來追求的錯誤在周圍經常能夠看到;
重視執行力,反對華而不實的喊口號;
不盲目迷信流行技術,對新技術通過不斷學習、測試和實踐的過程逐步掌握其特徵特點,也就是嘗試錯誤法(trial and error);
關心對商業需求深刻的理解;
等等,
總之踏實,誠實,務實,適應性等特徵都是自己追求的方向。

作為管理者,通過與成員的定期1on1,了解雙方的思路,得到各種反饋的過程十分重要。
同時也要遵重個人性格和習慣的多樣性,具有包容力。
當然管理者絕不只是做個老好人,凡事和稀泥,做好好先生,
畢竟明確的原則性是最基本的管理要求,需要做到有賞有罰。
一個只可意會,無法言傳的規章制度(技術選型時就是明確的指標定義和整體業務需求的平衡)是無法讓人心服口服的。
只要團隊成員適應習慣了這種管理手法,並且在實踐中做出了成績,
接下來就可以權力下放,疑人不用,用人不疑,使之充分發揮自身的獨立性,向自我管理自我提高的方向發展。

關於溝通和協作關係,工程師隊伍以外的stakeholder也非常重要,
這裡面包括了公司內部的企業經營者,產品和項目負責人,業務開發,市場人員,客服,媒體宣傳人員,法律專家,
也包括企業外部的合作夥伴。
真正理解公司的戰略目標,通過良好的互動和業績,
與各方建立起良好的信任關係,這是保證項目順利的最基本條件之一。

做為技術團隊的代表,
需要不使用專業術語,通過邏輯性的說明,
讓沒有技術背景的各方也能理解技術部門所需要的資源和進程;
對於來自各方商業方面的需求,應能夠通過系統分析,
完成可行性評估,資源評估,項目規劃,風險評估等一系列顧問諮詢業務。

作為一個不擅長言辭,沒有八面玲瓏的政治手腕的工程師,
不願意參加到派系政治里,只希望與所有人建立良好合作關係但又保持適當距離,
持續保持誠懇,謙虛,踏實,低調的工作作風。


第五,總結一下自己參與過的關於部門(某事業部)管理業務的內容,
具體包括:
人員計劃--根據中長期的業務計劃對人力資源不足的項目和部署補充新生力量;
人事--目標管理,業績考核,OJT培訓,1on1,考勤管理,個人成長計劃,管理手法培訓,新管理人員培養;
財務管理--預算和預算執行情況管理,包括人員計劃,軟硬體等設備投資,購買書籍資料,培訓費用,外包項目計劃,出差費用,工資獎金計劃,行業性組織會費,飲食交際費等;
部門管理--部門願景,組織構成,風險管理,安全性管理,ISMS認證,合作夥伴的合同管理,多項目的優先級管理;
部門會議運營等--安全衛生健康消防管理,部門經營會議,定期會,年會;
等等。

號稱是管理,其實雜活非常多,但是沒辦法,
公司發展到一定規模,法律中也有很多章程規定,
這些工作總得需要人干,雖然自己並不很擅長。
好在部門裡有各方面的專業人員,做好宏觀管理也就是了。

團結一致,集體的力量等詞彙好像很老生常談,
但現在深深體會到一個人的力量是有限的,
能在優秀的部下的支持下一起工作,
做出成績時的成就感真是非常幸福!!

最後列舉一下不足,也是今後的改進方向,如何提高自己還是一個長期的課題。。。
-非計算機專業出身,關於算法和網絡等基礎比較薄弱
-沒有java/go/swift/ruby/python 等語言的開發經驗,以前做程式設計師是用的是C/C++/Shell/VB為主
-比較內向,不喜歡拋頭露面,參加演講,研討會等面向外部的活動
-不善言辭,不善察言觀色,不是八面玲瓏,跟各種人打好交道的性格
-現在很多新技術不斷湧現,自己缺乏實際使用經驗,感到有些跟蹤不過來
-不擅長快速決策,更願意花時間仔細考慮,所以有時會猶豫不決
-思考模式有時可能會比較僵硬,比起年輕人缺乏靈活性
-有時會偏向保守,所以會擔心影響年輕人的積極性,比如新技術,新構架,新設計的採用等
-對用戶體驗,UI,UX等缺乏了解
-對於商業模式,服務企劃的經驗不多
-英語水平一般,聽說能力有待提高。
-還不成熟的高並發的工作方式。經常有大大小小十幾個項目在同時進行,如何分配好資源和優先級,不讓一些項目被阻塞,還需要繼續實踐

能把自己這十幾年的工作做個總結,理順些思路,還是很感謝這次交流機會的。

支 持 本 站: 捐贈伺服器等運維費用,需要您的支持!

發布時間: