大型軟體系統生命週期的絕大部分都處於「使用」階段,而非「設計」或「實現」階段。那麼,為何我們總是認為軟體工程應該首要關注設計和實現呢?
Google SRE團隊的核心成員在本書中分享了他們是如何對軟體進行生命週期的整體性關注的,以及解說這樣的做法為何能夠幫助Google成功地構建、部署、監控和運維世界上現存最大的軟體系統。您可以從中學習到Google工程師在提高系統部署規模、改進可靠性和資源利用效率方面的思考方式與具體作法。任何一個想要建立、擴展大規模整合系統的人都應該閱讀本書。本書針對如何構建一個可長期維護的系統提供了非常寶貴的實踐經驗。
本書分為以下四個部分:
.簡介:說明何謂網站可靠性工程(SRE)及其與傳統IT業界作法的差異
.原則:介紹SRE日常工作背後的指導原則:SRE的工作模式、行為方式,以及平時維運工作中關注的重點等
.實踐:探討SRE管理大型分散式系統的理念和實踐典範
.管理:介紹Google的訓練與團隊協作的方式
作者簡介:
Betsy Beyer
Google紐約分部專責SRE 的技術文件作家,之前曾為遍布全球的Google資料中心與Mountain View 硬體維運團隊撰寫文件,在搬到紐約之前,他曾擔任史丹佛大學技術寫作課程的講師。
Chris Jones
Google App Engine 的SRE。每天處理超過280億個請求,Chris之前的工作包括Google廣告統計、資料倉儲及使用者支援系統的維護,更早之前任職於學術單位的IT 部門,並參與競選資料分析,以及一些BSD核心的修改,他擁有電腦工程、經濟學及技術政策學的學位,也是一名有執照的專業工程師。
Jennifer Petoff
Google SRE 團隊的專案經理,工作地點在都柏林、愛爾蘭,她曾經負責管理大型全球專案,包括:科學研究、工程、人力資源及廣告等。
Niall Murphy
Google愛爾蘭團隊廣告SRE的負責人,投身網路業已經近20 年,目前是INEX的主席,他寫過許多科技文章與書籍,包括歐萊禮出版的《IPv6 Network Administration》以及很多RFC,目前正參與撰寫愛爾蘭網際網路發展史,他擁有電腦科學、數學,以及詩歌學的學位,目前與妻子和兩個兒子居住在都柏林。
各界推薦
名人推薦:
「能讓所有公司受益的高科技管理實務,只有Google能夠辦到的創新。」
—Thomas A.Limoncelli, 《The Practice of Cloud System Administration》共同作者
「web高可用性服務管理人員必讀的一本書」
—Adrian Cockcroft, 前任Netflix雲端架構師
「不管是為了自己還是公司,你都應該熟讀本書並動手實踐這些理念」
—Jez Humble, 《Continuous Delivery》、《精實企業》共同作者
名人推薦:「能讓所有公司受益的高科技管理實務,只有Google能夠辦到的創新。」
—Thomas A.Limoncelli, 《The Practice of Cloud System Administration》共同作者
「web高可用性服務管理人員必讀的一本書」
—Adrian Cockcroft, 前任Netflix雲端架構師
「不管是為了自己還是公司,你都應該熟讀本書並動手實踐這些理念」
—Jez Humble, 《Continuous Delivery》、《精實企業》共同作者
章節試閱
SRE的基本方針
雖然每個SRE團隊都有自己的工作流程、優先權定義以及日常工作規範,但是所有的SRE團隊都遵循一套共同的核心方法論。
一般來說,SRE團隊要承擔以下幾類職責:提升可用性、最小延遲、效能最佳化、效率最佳化、變更管理、健康狀態監控、緊急應變以及容量規劃。SRE管理階層針對這些內容制定了一套完整的溝通準則和行事規範,規定SRE如何操作Google正式作業環境,以及如何和產品研發部門、測試部門、終端使用者進行有效溝通,這些準則和規範能夠幫助每一個SRE部門維持均衡的研發和維運負荷。
確保長期關注研發工作
Google將SRE團隊的維運工作限制在50%以內,將剩餘時間花在研發專案上。實際作業上,SRE管理人員應該經常度量團隊成員的時間分配,必要的話,可採取一些暫時性措施將過多的維運壓力移回開發團隊處理。例如:將正式作業環境中發現的Bug和產生的工單轉由研發管理人員去調度,或者將開發團隊成員加入到oncall體系中共同承擔輪值壓力等。這些暫時性措施必須持續到SRE的維運負荷降到50%以下為止,這種措施實際形成一種良性循環,激勵研發團隊設計、建構出不需要人為干預、可以自主執行的系統,只有整個產品部門都認同這個模式,認同50%安全底線的重要性,才可避免造成過度的維運負荷。
SRE處理維運工作的一項準則是:在每8~12小時的on-call期間最多只處理兩個緊急事件,這個準則可確保on-call工程師有足夠的時間追蹤緊急事件,因此SRE能正確地處理故障、恢復服務,並且撰寫一份事後報告。如果on-call期間要處理過多問題,那麼每個問題就不可能被詳細調查,維運工程師甚至沒有時間從中學習。假使小規模部署都還無法做到合理警報,等規模擴大之後這個情況就會更嚴重;相對而言,若專案的緊急警報非常少,能夠持續穩定運行,則配置這麼多on-call工程師可能就是浪費時間。
所有的產品事故,無論有沒有觸發警報,都應該有對應的事後檢討,請注意,如果某項產品事故沒有觸發警報,事後檢討意義可能更重大:因為它可能是監控系統的漏洞。事後檢討應該包括以下內容:事件從發生、發現到解決的全部過程、事件的根本原因、預防或最佳化的解決方案。Google秉持對事不對人的事後檢討準則,事後檢討(postmortem)的目標是儘早發現和堵住漏洞,而不是透過流程去繞過和掩蓋它們。
可靠地進行大規模發行
Google這樣的網際網路公司比起傳統公司,可以更快地發行和迭代新的產品和新的功能。SRE在整個流程中可以確保快速迭代不會影響到網站的穩定性,為此SRE還專門成立「上線協調小組」,負責為開發團隊提供技術顧問和支援。
這個小組維護一份「上線檢核表」,內容包括每次系統發行需要檢查的常見問題,及避免常見問題的手段。這份清單在實務上被證實是保障發行可靠性的重要工具。
Google有一名為Keyhole的服務,這個服務負責提供衛星圖像給Google Maps以及Google Earth。平時Keyhole每秒處理幾千筆圖像請求,2011年聖誕節前夜,流量突然暴增到平日峰值的25倍,接近每秒100萬筆。是什麼造成此次流量暴增呢?
聖誕老人要來了!(聖誕老人追蹤器)
幾年前,Google和NORAD(北美防空司令部)合作推出聖誕節主題網站,上面顯示聖誕老人在全球各地發送禮物的紀錄,允許任何人追蹤聖誕老人的行蹤,該網站是半娛樂性質,允許使用者在上面添加自己收到的禮物和地理位置,實際上收集了很多資料以提高地圖的精確性。網站的一項重要功能是「虛擬飛行路線」,利用衛星圖像即時追蹤聖誕老人的行蹤。
雖然這樣的網站是半娛樂性質,但它的發行具有一切難度高和危險性強的特點:
.不可改變的截止日期(Google可不能因為網站沒有上線而不過聖誕節)。
.大規模宣傳活動。
.數百萬的使用人群。
.流量增速快(所有人都會在平安夜瀏覽這個網站)。
可別小看幾百萬個小孩同時更新網站,這完全具備搞垮Google全部服務的潛力。
SRE團隊為了這次發行做了很多基礎設施的變更,以確保聖誕老人發送禮物的過程不受影響,沒有人願意看到小朋友無法使用網站而傷心,我們甚至將產品內嵌的幾個保護性功能開關命名為「讓小孩子哭吧」(Make-children-cry)。SRE的一支特殊團隊「上線協調工程師」(LCE)負責預測發行可能出現的問題,並負責協調不同的開發小組。
發行一項新產品或者新功能對每個公司來說都是一場考驗,幾個月,甚至幾年的努力都是為了向世界宣布這一刻。傳統公司的發行週期很長,而網際網路公司的發行週期非常不同,讓快速發行、快速迭代變得簡單的原因是他們僅僅需要在伺服器端發行,而不需要發送到每個使用者的電腦上。
Google將發行定義為使用者可見的應用程式更新,依照發行的特點:屬性及時間、發行步驟多寡、發行複雜程度,每次發行的流程也不一樣,按照這個定義,有時可以做到每週發行70次。
這種發行速度要求我們建立和維護一組精簡的發行流程,一家每三年才發行一次新產品的公司可能不需要詳細的發行流程,因為下次發行時,之前建立的項目可能都過時了。這種公司也不可能有足夠的機會建立出好的發行流程,因為無法透過反覆施行來提升流程的速度和可靠性。
處理用戶端濫用行為
最簡單的用戶端濫用行為是某個更新間隔的設定問題,一個每60s同步一次的新用戶端,會比600s同步一次的舊用戶端產生10倍負載,重試邏輯也有一些常見問題會影響到使用者觸發的行為,或者用戶端自動觸發的行為。以一個目前處於超載狀態的服務為例,該服務由於超載,某些請求處理會失敗,如果用戶端重試失敗請求,會對已經超載的服務造成更大負載,於是造成更多重試、更多負載。用戶端這時應該降低重試的頻率,一般需要增加指數型增長的重試延時,並仔細考慮哪些錯誤值得重試。例如,網路錯誤通常值得重試,但是4xx HTTP錯誤(表示戶端的請求有問題)一般不應該重試。
故意或無意的自動請求同步會造成驚群效應(如第24、25章所描述),這是另外一個常見的濫用行為。某個手機APP開發者可能認為半夜兩點是下載更新的好時機,因為使用者這時可能在睡覺,不會被下載影響。然而,這樣的設計會造成半夜兩點時有大量請求發往下載伺服器,每天晚上都是如此,而其他時間則沒有任何請求,處理這種情況,每個用戶端應該引入一定隨機性。
其他週期性程序也需要引入隨機性,回到之前說的那個重試場景:某個用戶端發送一個請求,當遇到故障時,1s之後重試,接下來是2s、4s等。沒有隨機性的話,短暫的請求極值可能會造成錯誤比例升高,這個週期會一直循環,為了避免這種同步性,每個請求延時都需要一定的抖動(也就是加入一定的隨機性)。
伺服器端控制用戶端行為的能力也是一項重要工具,對安裝在設備上的APP來說,這種控制表示用戶端週期性與伺服器聯繫,並且下載組態檔。組態檔可能會啟用或禁用某些功能或者調整參數,例如多久同步一次和重試的頻率等。
用戶端組態檔甚至可以啟用全新的使用者可見功能,透過將新功能的程式在啟動之前提前發行到用戶端,可以明顯降低該發行的危險性。發行新版本也能變得更簡單,原因是不需要處理功能啟用與維護多個平行的發行軌道,發行一系列有著不同發行時間的獨立功能來說就更重要了,否則需要維護各種版本組合。
透過加入這種功能,讓問題出現時,中止發行更容易,可以簡單地關閉該功能,修復程式碼,再發行新版APP。如果沒有這項設定,就需要去掉這項功能,製作新版本,再發行到所有人的設備上。
超載行為和負載測試
超載是一種複雜的故障模式,需要特別注意。意料之外的成功,經常是服務發行時出現超載的常見因素,其他原因包括負載平衡問題、實體機故障、同步用戶端行為、外界攻擊等。
在簡化的模型中,假設實體機的CPU用量與某個服務的負載線性相關(如請求數量或處理資料量等),一旦可用的CPU耗盡,處理過程就會變慢。不幸的,真實的服務很少按照理想模式運轉,大部分服務在沒有滿載的情況也會變慢,可能因各種快取因素造成,例如CPU快取、JIT快取及其他的資料快取等。
隨著負載上升,經常有一段時間CPU用量和負載線性同步增長,回應時間基本保持固定。當負載持續上升到某一數量後,很多服務在超載之前會進入一個非線性轉折點。
常見的例子是,回應時間上升,造成使用者體驗下降,但是不一定會造成故障(然而相依服務的速度變慢可能會導致RPC逾時,而造成使用者可見的錯誤),最壞情況是在超載情況下,服務進入完全死鎖狀態。
舉個實際的負載行為:某個服務在收到後端錯誤時會記錄除錯資訊,但因記錄過程比處理後端的成本更高,當該服務進入超載狀況,某些後端請求逾時,服務會花更多的CPU時間來記錄除錯資訊,造成更多的請求逾時,最後進入完全死鎖狀態。對執行在JVM上的服務來說,這種死鎖狀態有時稱為「垃圾回收死亡螺旋」(GC thrashing),對於這種情況,虛擬機會更頻繁執行記憶體管理,不停地想要回收記憶體,直到大部分CPU資源都被記憶體管理佔用。
不幸的,從理論上很難預測某個服務的超載反應,因此,不管是從可靠性角度還是容量規劃角度,壓力測試對多數發行來說都非常很重要。
SRE的基本方針
雖然每個SRE團隊都有自己的工作流程、優先權定義以及日常工作規範,但是所有的SRE團隊都遵循一套共同的核心方法論。
一般來說,SRE團隊要承擔以下幾類職責:提升可用性、最小延遲、效能最佳化、效率最佳化、變更管理、健康狀態監控、緊急應變以及容量規劃。SRE管理階層針對這些內容制定了一套完整的溝通準則和行事規範,規定SRE如何操作Google正式作業環境,以及如何和產品研發部門、測試部門、終端使用者進行有效溝通,這些準則和規範能夠幫助每一個SRE部門維持均衡的研發和維運負荷。
確保長期關注研發工作
Goo...
作者序
如果用一個語詞來描述Google的歷史,那就是不斷地「擴大規模」(scaling up)。Google的成長經歷是電腦產業中數一數二的成功故事,標記著整個社會朝向IT為中心的商業模式而轉變。Google 很早就開始實踐IT與商業模式的結合,也是向社群推廣DevOps理念的先鋒。本書就是由公司各個部門切身參與、甚至主導了整個產業轉型實踐的人寫成的。
Google是在系統維運工程師轉型的階段發展壯大的,它的發展史就像是對傳統的系統維運理念發出的革命宣言:我們無法按照傳統方式維運Google系統,必須要思考一種新的模式,但是同時我們也沒有時間等待其他人驗證和支援我們的理論。在《Principles of Network and System Administration》一書的介紹中,我提出了一種觀點:系統維運本質上是人與電腦共同參與的一項系統性工程。當時有些評論者強烈反對這種觀點:「這個產業還遠遠沒有成熟到可以稱為一項工程」。在那時,我甚至對整個維運產業產生了懷疑,認為這個產業在個人英雄主義與神秘色彩中已經永久地迷失了自己,無法前進。但是,這時Google誕生了,Google的高速發展將我的預言變成了現實,我之前的定義變成具體的詞語:SRE,網站可靠性工程師。我的幾個朋友親身參與這個新職業的創立,用軟體工程理念和自動化工具定義了這個產業。一開始,他們顯得很神秘,Google公司內部的體驗和整個產業也格格不入,Google 太特殊了!久而久之,公司內外交流逐漸增多。這本書的目標就是將SRE的思想和實務介紹給整個產業,以促進交流。
本書不僅僅介紹Google如何建設、維護其富有傳奇色彩的大型運算叢集,更重要的是在過程中,Google工程師團隊如何學習、成長、反覆修改,最後定義出一套完整的工具和科技系統。IT產業大多自我封閉、交流過少,很多從業人員都或多或少地受教條主義的限制。如果Google 工程師團隊能克服這個慣性,保持開放的精神,那麼我們也能夠一起和他們面對IT業界最尖端的挑戰。這本書由一群有共同目標的Google工程師寫就的短文集結而成,作者群聚集在同一家公司旗下,為了共同目標努力,本身就是一件很特別的事情。在本書的各個章節之間經常能看到軟體系統的共同點,以及工作模式上的共通之處,我們經常可以從多個角度分析不同的決策選項,了解它們是如何一起解決公司內部的利益衝突。這些文章並不是嚴謹的學術研究論文,而是這些人的切身經歷,雖然本書的作者們有著不同的工作目標、寫作風格及技術背景,但是他們都嘗試真誠地描述自己遇到的問題和解決的經歷,這和IT界的普遍文風截然不同,風格迥異。有些作者會宣稱:「不要做A,只有做B才是正確的」,另一些作者會更謹慎,行文更富有哲理,其實這恰恰代表整個IT產業內不同個性融合的現狀。而我們做為讀者,做為觀察者,並不了解整個Google的歷史,也沒有參與具體的決策過程中,無法完全體會當事人所面臨的糾纏不清的挑戰,只能帶著謙遜的態度遠遠旁觀。在閱讀本書的過程中,相信讀者一定會產生許多疑問:他們當時為什麼沒有選擇X?如果他們選擇Y,結果會是怎樣?如果多年之後回頭再看,這個選擇還會是正確的嗎?這些問題,恰恰是閱讀本書的最大收穫,因為我們第一次有機會將自己的經歷、選擇和本書陳列的決策邏輯相互對應,從中發現不足和缺陷。
這本書的成書過程也堪稱奇蹟。今天,我們能感受到整個業界都在鼓吹厚顏無恥的「給我程式碼,其餘免談」(just show me the code);開源軟體社群內部正在形成一種「別問我問題」的風氣,過於強調平等卻忽略領域專家的意見。Google是業界為數不多的,願意投入菁英力量鑽研本質問題的公司,而且這些公司菁英很多都有工學博士學位。工具永遠只是解決方案中的一個小小元件,用來連結日益龐雜的軟體、人和海量資料。這本書中沒有萬能仙丹,沒有什麼東西能解決一切問題,本書的宗旨是:相對於最終的軟體結果、架構設計而言,真實的設計過程和作者本身的思考經歷更具價值。實作細節常常時過眼雲煙,但是文件化的設計過程卻是無價之寶。有機會了解到這些設計的內幕真是太難得了!
總而言之,本書就是Google的成長經歷,實際上就是由相互重疊的故事所組成,書中內容正好說明擴展一套電腦系統,要比簡單按照書本上的標準架構放大困難得多。一家公司的成長,意味著整個公司商業模式和工作模式的擴展,而不只是單純的資源擴張。單就這一點,這本書就物超所值了。
IT業界並不流行反躬自省,我們不斷重複發明各種系統。多年來,只有USENIX LISA大會論壇以及其他幾個專注於作業系統的會議會討論一些IT基礎設施的設計和實作。多年後的今天,IT業界已有極大變化,但是本書仍然彌足珍貴:它詳細記錄了Google邁過分水嶺時期的完整過程。很顯然,這些經歷沒有辦法完全複製,也許只能模仿,但是卻可以啟發讀者、指引未來。本書作者們表現出極大的真誠,顯示了謙遜的風格,以及極強的凝聚力、領導力。這些文章記錄作者們的希望、擔憂、成功與失敗的經歷。我向這些作者們和編輯們的勇氣致敬,正是這種坦率,讓我們能夠做為旁觀者和後來人,從前人的經歷中學習到最寶貴的知識。
如果用一個語詞來描述Google的歷史,那就是不斷地「擴大規模」(scaling up)。Google的成長經歷是電腦產業中數一數二的成功故事,標記著整個社會朝向IT為中心的商業模式而轉變。Google 很早就開始實踐IT與商業模式的結合,也是向社群推廣DevOps理念的先鋒。本書就是由公司各個部門切身參與、甚至主導了整個產業轉型實踐的人寫成的。
Google是在系統維運工程師轉型的階段發展壯大的,它的發展史就像是對傳統的系統維運理念發出的革命宣言:我們無法按照傳統方式維運Google系統,必須要思考一種新的模式,但是同時我們也沒有時間等待其他...
目錄
PART I 概覽
第1章 緒論
第2章 從 SRE 的角度看 Google 正式服務環境
PART II 指導原則
第3章 擁抱風險
第4章 服務水準目標
第5章 減少瑣事
第6章 監控分散式系統
第7章 Google 自動化系統的演進
第8章 發行工程
第9章 簡單化
PART Ⅲ 具體實踐
第10章 基於時間序列資料進行有效警報
第11章 on-call
第12章 有效的故障排除技巧
第13章 緊急應變
第14章 緊急事件管理
第15章 事後檢討:從失敗中學習
第16章 事件追蹤
第17章 測試可靠性
第18章 SRE 部門中的軟體工程實務
第19章 前端伺服器的負載平衡
第20章 資料中心內部的負載平衡系統
第21章 處理系統超載
第22章 處理連鎖故障
第23章 管理關鍵狀態:利用分散式一致化來提高可靠性
第24章 分散式任務排程系統
第25章 資料處理管線
第26章 資料完整性:讀寫一致
第27章 可靠地進行大規模發行
PART Ⅳ 管理
第28章 迅速培養 SRE 加入 on-call
第29章 處理插斷性任務
第30章 透過嵌入 SRE 的方式幫助團隊從維運超載中恢復
第31章 SRE 與其他團隊的溝通與協同合作
第32章 SRE 參與模型的演進歷程
PART Ⅴ 總結
第33章 其他產業的實務經驗
第34章 結語
附錄A 系統可用性
附錄B 正式作業環境維運過程中的實踐典範
附錄C 事件狀態範例文件
附錄D 事後檢討範例
附錄E 上線協調檢核表
附錄F 產務會議紀錄範例
參考文獻
索引
關於作者+出版記事
PART I 概覽
第1章 緒論
第2章 從 SRE 的角度看 Google 正式服務環境
PART II 指導原則
第3章 擁抱風險
第4章 服務水準目標
第5章 減少瑣事
第6章 監控分散式系統
第7章 Google 自動化系統的演進
第8章 發行工程
第9章 簡單化
PART Ⅲ 具體實踐
第10章 基於時間序列資料進行有效警報
第11章 on-call
第12章 有效的故障排除技巧
第13章 緊急應變
第14章 緊急事件管理
第15章 事後檢討:從失敗中學習
第16章 事件追蹤
第17章 測試可靠性
第18章 SRE 部門中的軟體工程實務
第19章 前端伺服器的...