1. 程式人生 > >孫宇聰:來自Google的DevOps理念及實踐(上) – 運維派

孫宇聰:來自Google的DevOps理念及實踐(上) – 運維派

SRE(Site Reliability Engineering)是最早由Google提出,又經由Google發展完善的一個嶄新運維理念。如今SRE已成為一個涵蓋運維理念、思路、組織架構和具體實踐的完整體系。數人云推出SRE系列教程,由SRE經驗豐富的技術大牛們為大家分享運維一線的獨家乾貨,揭示SRE背後的祕密。

今天為系列教程第一期,我們邀請了前Google SRE、《SRE Google運維解密》的譯者孫宇聰與大家進行了線上分享。本文為上篇,講述了SRE的基本概念和核心原理。與孫老師本人一樣風趣幽默的文章,小數希望大家閱讀愉快:)

今天與大家分享的內容是關於最近我翻譯的這本書,據說反響還不錯,今天借這個機會聊一聊書中的內容,並與大家分享一下我回國兩年多以來,Google經驗在國內的一些思考和落地實踐。

什麼是SRE?

很多時候國內把DevOps的範圍定得有點狹窄, DevOps這件事情在國外更多是整個行業內的一個趨勢。DevOps是一種模式,主要是讓IT相關的東西與商業結合得更緊密一些,迭代速度變得更快一些,所以它適用於各個行業。今天說的SRE,我認為也是在運維行業上的一部分。

概括來說,我認為《SRE Google運維解密》這本書是一個文集。GoogleSRE全球一千多人,這個組織在公司裡相對比較小眾,但又是一個比較重要的部門,整個Google所有業務線的運維環境都由SRE來負責。SRE是一個非常分散的組織,每個業務線、每個部門其實都有自己的SRE小團隊。這本書裡共有一百多個作者聯合寫成,其中也包括我以前所在的團隊,我們做過的一些Project也在書中也有提到,所以它是一本文集。我與原著的三個編輯聊天時,他們說成書最大的難處就是刪減內容,當時徵集來的內容大概有一千多頁,最後刪到了五百多頁。這也是這本書比較有意思的一個花絮。

回到這本書的宗旨, SRE到底是什麼?SRE是Google發明的一個詞語或者新定義的一個職業。以前這個運維角色,大家叫運維,美國叫Operation。現在Google把這個職位擴充套件為SRE,就是用軟體工程師的方法和手段,招了一些軟體工程師來解決運維的難題,這是SRE的官方定義。

傳統運維模式的弱點

現在傳統的計算機行業的運維方式,大部分都是採用系統管理員的模式。大家最熟悉的運維方式是這樣:招聘一些系統管理員,他們有負責採購機器的,有負責維護資料中心的,也有專門維護資料庫的等等。系統管理員模式有幾個特點,他們只是把一些現成的元件組裝起來,並不會自己開發和創造新的系統,比如拿了MySQL把它跑起來,或是研發部門開發出來的新程式碼組裝成之後提供這樣一個服務。這是運維部門的一個特色,負責把這個東西執行好。

舉一個例子,在美國的時候我們經常自嘲,說自己是流水線上的工人。因為這個流水線實際上是別人設計出來的,總得有人去操作這個機器,而我們就是一線的操作流水線的工人。又比如,我們好像是發電站裡的工作人員,又或者是飛機駕駛員。飛機駕駛員就是開別人造出來的飛機,這和運維部門的職責很像。

那麼這樣一個運維部門的職責包括哪些呢?首先最重要的是應急事件的處理,這是重中之重,也是最唯一的職責。其次是常規更新,現在的業務發展越來越快,每週都有新的東西上線,比如說今天要買新機器,明天要改IP地址,大家可能80%的投入都是在這些事上,這就是系統管理員或者是現在運維行業的工作模式。

但是系統管理員模式有一個最大的弊端,按照傳統的組織架構模式或者是這種運維模式執行會導致這個團隊持續擴張,業務越來越多,需要不停的招人去應付各種各樣的事。剛開始接手生產的時候,也許一週就出一次事或者是需要更新一次。因為人的溝通能力總是有限的,招了五個人之後,這五個人之間的傳達問題就形成了一個困難。當你把一個精神傳達給這五個人,他們事後執行出來的結果都不一樣,這就是傳統模型一直想要解決的問題。但是這種模型也有好處,就是市場招聘比較容易。

Google有幾個比較重要的特點,首先它的部署規模非常大。Google到今天已經十八年了,剛開始前幾年公司所有的人平時寫程式碼,週末去機房接機器。因為它擴充套件速度特別快,部署規模非常大。如果按照傳統的系統管理員的那種模式操作,這個機櫃歸你,這個機櫃歸他,再下一個歸另外一個人,那麼Google招人的速度一定趕不上機器增加的速度,所以Google是被逼迫創造了這樣的職位,因為沒有辦法安排團隊做如此大規模的運維。

傳統的運維模式還有一個更大的問題,它過於強調專業化。比如一個人是做網路的,他只做網路其他都不管,全公司可能只有他懂網路,因為他不停的在網路上投入時間,集中力氣把這個事情做好。這樣一個結果就是會發現運維部門沒人能休假,一出事只有一個人能解決問題。不僅僅是網路,特殊硬體、一些第三方服務都存在這個問題。這就導致了知識沒法共享,人靈活性受到限制,整個組織的靈活性也受限制。這個問題,我認為它最終形成了一個負反饋的迴圈,每個人之間越是互相隔離,越是沒有辦法提高,導致服務質量上不去。最大的問題是,招來更多的人其實也不解決問題,因為這個部署規模不斷擴大,人之間的知識不能共享,所以招來的人只能運維新的裝置,舊的裝置還是這些人在做。

這是一個怪圈。回國之後我與很多公司的朋友都聊過這個問題。以前大家講Oracle這樣的公司存在老DBA,說老DBA都是難得一見的,深居簡出,但是你有什麼問題,只有他能解決,其實這在Google這個語境裡這是一個比較不健康的狀態。SRE的一大特點就是想請假的時候隨時請假,每一個人都可以請假;當出現緊急情況的時候,當天值班的人真的可以處理他負責的這個服務所有的問題。

Google SRE的起源與特點

回到最開始,Google SRE的VP叫Ben Treynor,他是一個資深的軟體開發經理。2003年他加入公司第一個任務,是組建一個7人的“生產運維小組”。很快他發現如果想把這件事情做好,也就是把搜尋服務運維好的話,按照Google機器增加的速度,傳統的模式絕對是不可能的。機器增加的速度,系統複雜度增加的速度遠比人增加的速度要多得多。所以他組建的團隊有以下三個特點,注意,這裡我認為其實更多的是事後的總結。首先,他的執行方式是像組建一個研發團隊一樣來組建這個運維團隊。他招了很多他熟悉的研發工程師,這些研發工程師從開發能力上沒有任何問題,用現在流行的話就是全棧工程師,什麼都會做。第二點,這些人對系統管理比較有熱情,懂一些Linux核心知識、網路層的知識。第三點,最關鍵的是這些人鄙視重複性勞動,碼農最痛恨的是什麼事,就是反覆做同一件事。他把這些人聚到一塊,然後讓他們執行以前傳統公司運維人員來做的事情,很自然這些人不願意手動幹,於是就寫程式幹。多快好省,同時寫程式還有一個好處,就是可以把一些最佳實踐、方式、流程、方法都固化成程式碼,用這種方式去應對規模性的擴張,去應對複雜度的上升。

這些是SRE跟傳統的運維模式最不同的一點,就是招的人研發為主,做的事也是以研發為主。這是當時SRE成立背後的故事,這些年來我認為他們做得最好的一點是一直在維持了一種平衡。將運維部門從傳統執行部門往上提升,打破了傳統的界限。就像剛才說的DevOps,很多人理解為就是讓研發部門做運維的事,或者運維部門做研發的事情,但實際上DevOps在國外的定義更寬泛一點。DevOps的思想更多的是說把整個開發流程的界限打通,產品有的時候也要幹一些研發的事,研發有時候把這個資訊要很快的反饋給這個產品,開發和運維或者QA和運維之間的界限也打通。所以現在去搜DevOps的圖片,會發現IBM這些人都在講圈圈,說以前是產品研發都是一條線直著來,而現在都是轉圈的,這就是DevOps理論。

按照這個理論來說,SRE就是DevOps的思想在開發和運維之間的一個平衡。

SRE的工作職責

這個圖是我發明的,書中沒有提到。書裡大概有二十多章的內容是在講SRE的各種日常工作,簡單提了一下它的金字塔模型,於是我歸納總結了一下。這裡是由下至上,下面的事份額比較大一點,上面的事份額比較小一點,分了三類。第一類,運維部門最重要的是應急響應這個問題,因為業務越來越大,與運營的結合越來越緊密,很多時候要處理的事情更多的是商業和運營上的事,也包括軟體上的問題,這個部門最特殊或者最唯一的職責就是應急響應。之上是日常運維,保證機器能夠正常更新、快速迭代。再往上是輸出一些工程研發,無論是做工具,還是做高可用架構、提高可靠性,這些都是最上層的東西,只有把底下全部做好了才能說到上面。

應急響應

應急響應是運維部門在公司最獨特的一點,表現為當公司出現問題時,應該找誰或者流程應該是怎樣的。我回國之後見了不少初創企業,他們網站出問題了,往往是CEO先發現,CEO打電話“哎,這個到底是怎麼回事啊”,然後每一個人都說“不知道啊,不是我負責呀,我得找誰誰”。不管多大一件事都得傳遍整個公司,整個效率非常混亂。

我在Google待了八年時間,這樣的流程也經歷過,但是最近這幾年Google非常重視這一點,建立了一整套應急事件處理方式。首先要有全面監控,監控這件事情是持久不斷的,重中之重。SRE所有人都要非常瞭解整個監控系統在所有業務中的部署實施,其實這是我們平時花精力最多的地方。監控系統裡面對整個系統所有方面都有監控,不光包括業務指標,也包括效能指標、效率指標。監控應該平臺化、系統化,不停的往上積累,多做一些模板,同質化的系統就可以用同樣的方法去做監控。

第二點是應急事務處理,應急事務處理分兩部分,第一部分是演習,另外一部分是真正的處理流程。如何把它做好?實際上就是要不停的去演習、去做這個事情。像剛才舉的例子,網站掛了,首先不應該CEO先發現,而應該是監控系統或者報警系統先告警,在發現之前就很應該明確這個東西應該誰排查,誰處理,這個資訊應該早就發給合適的人去處理,甚至他應該早就在做了。如果發生特別大的,需要跨部門之間協作的問題,那不應該只是領導現場調配,而是整個組織每個人都明白這個流程應該是怎麼樣的,直接就做。Google甚至可以做到在一次事故中間兩地交班,某個團隊處理一半,然後我交接給另外一邊團隊,就下班回家了,持續不停的有人繼續跟蹤處理這件事情,而不會出現問題。這樣一個模式是我覺得非常值得我們思考的。

處理完問題之後,要總結。之前聽過的一個故事是,某公司業務出現了一個事故,大家加班加點,十幾個小時沒睡覺把這事搞定,然後領導過來就說了一句“大家辛苦了,回家睡覺吧”。但是,其實在這個時候我要說,領導光說這個其實恰恰是不夠的。領導在這裡應該問:為什麼加班啊?這個事情為什麼會發生啊,下次能不能不發生,大家能不能不加班,能不能不熬夜?這樣才對, 能做到事後總結這個事情很難,但只有把這個做好了,才能降低以後問題發生的機率。

日常運維

日常運維做得最多的可能是變更管理。業務現在發展非常快,迭代速度、迭代週期非常快。其實這件事情能做好,能夠做到無縫、安全、不停的變更管理,是運維部門能給公司做的最大貢獻。

第二個,容量規劃,當規模大到一定程度的時候,就需要有人來回答這個問題——到底要買多少新機器,能否保證明年的效能、效率,那誰來負責這件事呢?SRE部門提出這些方案,然後要確保這些指標、這些東西是有資料支撐的,確實能解決問題的。

工程研發

工程研發雖然做得少,但是工作很關鍵。SRE在工程研發上主要的工作,首先是幫產品部門確定一個SLO。SLO是一個服務指標,每一個產品都有一個服務指標。任何系統都不可能是百分之百可靠的,也沒有必要做到百分之百可靠。這裡得有一個目標,比如說可以每個月中斷幾分鐘。這件事情是要產品部門考慮清楚的。比如我之前在YouTube做視訊儲存、視訊點播的時候,要考慮每個視訊到底是存一份還是存兩份的問題,將這種問題放到一個非常大的部署規模裡面的時候,只有產品部門能夠拍板。說到底是要不要花這個預算,要不要花這麼多錢去提高0.1%的可靠性或者0.01%的可靠性。

另外一點是無人化運維。大家都看過《黑客帝國》吧?一醒來發現大家都是電池,都是為機器服務的。其實把這個比喻放在運維部門非常合適。因為如果不停的開發出需要人來操作運維的系統,結果大家最後都是電池,明顯是不可持續的。如果不停的產生這種需要人來操作的東西,不停的招人,最後就變成不停的運維這個東西。把整個流程自動化,建立一個能夠應對複雜業務的平臺,這就是工程研發上最需要的東西。

SRE模型成功的關鍵要素

SRE在Google有十幾年的歷史了。這個模型是如何成功的?我總結如下幾點:

職業化

運維行業從來都說不清楚自己是幹嘛的,這是不對的。很多人認為會操作Linux,或者是DBA、會配網路,就算運維了。實際上運維的範圍要比這個大得多。運維應該是負責公司業務正常運轉的角色,這才是真正的運維。在出問題的時候能解決問題,保障業務連續性,甚至避免問題發生,這才是運維職業的定義。

具體如何做呢?推演和演習。

推演是給你一套系統,你要分析出來它會有什麼樣的失敗模式。我們當時經常在黑板上畫系統圖,大家一起討論如果這個元件出問題了會發生什麼情況,使用者到底還能不能看視訊了,使用者購買流程還能不能走通。實際上這些過程很多時候軟體開發是不考慮的,但是如何拆分、如何去保證每個環節的可靠,這才反是運維這個行業最關鍵的一點,所以一定要做這種推演。只有這種推演才能輸出改變,讓系統更可靠。

第二點是演習。我們當時每週都會進行一次小型災難演習,例如把以前出現的問題拿出來一個,讓新加入團隊的人去演習,所有其他的人也都要去參加。這裡主要是觀察新人到底是怎麼思考這個系統的,新人做出的決定到底是不是正確的。因為一個人做出的決定是不是正確的實際上取決於系統給的反饋到底是不是對的。Google認為運維複雜系統不是一個靠智商和記憶力就能解決的問題,不能依賴人一定要知道這段話或這個知識點,而是要知道一種方法,知道如何去排除問題或排查問題。運維繫統應該提供足夠的資訊,讓輪值的人能夠用正確的方法去處理問題。這很像是背英語辭典和會用英語聊天的區別,你再怎麼背辭典關鍵時刻也是要查辭典的,但是真正能運用這些資訊解決問題,是比較難的。

此外,要區分責任和指責。責任和指責是兩個事情,但是很多公司的運維經常分不清楚。什麼叫責任,就是這個事到底誰負責。但是指責是另外一回事。例如一個員工敲錯了一個命令,大家說 “都是因為他的錯,給他扣工資、扣獎金,讓他三天不吃飯”,但這其實並不真正解決問題。再例如,比如說一個系統設計電源插座,沒有仔細考慮,很容易被人踢到,結果有人真踢到了,整個機房斷電了出了很大的事故。那麼從Google的理念來說這裡不是人的問題,而是系統設計的問題。這裡是不是應該有兩套電源,是不是應該有保護?只有從系統設計問題的角度出發才能真正解決問題,而指責這個踢到插座的人,讓他一個月不上班,甚至當時開除也並不能解決系統的設計問題,下回總會還有人踢到。

​說一個故事,故事的內容是一個事故。某個資料中心有一排機器要斷電,資料中心的人發了一個工單告訴操作員要把這個開關給關了。然後這個操作員去關,他關掉了開關,但是發現這一排機器的燈沒滅,另外一排的燈卻滅了——按錯開關了。他檢查一下發現按錯了,“啪”把另外一個開關也關了,然後再把這一排機器給啟動,結果由於啟動時候過載導致整個資料中心都斷電了,擴大了問題。如果單純只是指責,這個人肯定完了,起碼獎金沒有了,能不能保證工作都不知道。但是Google 更關注的是這個東西為什麼會容易出錯,要麼是開關顏色不對,要麼是相同機器的操作方式靠得太近了,會讓人產生這種錯誤的判斷。所以你看Google的機房裡都是五顏六色的,因為這樣確實有用,比如熱水管是紅色的,製冷管是藍色的,所以查起來很容易,區分起來很容易,儘量減少了這個問題。這個設計的思想在SRE日常工作裡貫徹得非常深,每人在流程或工作的時候都要考慮到有沒有被誤用的可能,然後如何避免誤用。

專業化

專業化體現在什麼程度呢?要真正的去寫程式碼,要能給業務系統或者給研發寫的東西挑出問題,提高可靠性。

第一,減少瑣事。運維中有很多虛假的工作。每天很忙,然而又不解決問題,做了很多假的工作。大家看起來好像很忙,一個螢幕上十幾個視窗,各種刷屏,但完全不解決問題。更好的方式是用自動化、系統化、工具化的方式去消除這種瑣事的存在。如果永遠靠人工,那永遠都閒不下來。

第二,回到SRE,SRE制度裡有一條紅線,運維的人只能把一半的時間花在運維上,另外一半的時間必須搞工程上、研發上的東西。研發可以是寫工具,可以是參與系統設計,參與可靠性的提高,但是要保證運維不能只幹運維。

第三點,我認為也是比較缺少的,運維部門光有責任沒有決策權,所以大家都說一出事故,運維就背黑鍋。怎麼不背黑鍋呢?說改這兒、改那兒,然後發現沒有人批准改動,這是最大的問題。SRE做的最好的一點是管理層對SRE的工作方式非常認可、非常支援,他們認為服務質量是服務的一個重要指標。一旦上升到這個高度,SRE部門提出一些要求就比較容易理解,得到支援,因為他們是有事實根據的。當GoogleSRE發現生產出現問題的時候,標準的解決辦法就是暫停所有更新,確保業務穩定。舉個比較極端的例子,像剛才說的如果發現線上系統有問題的情況下,SRE是有權利拒絕接受業務更新的,只允許研發部門修bug,不允許加新功能。這個爭議我在過去八年見過為數不多的幾次,開發可以一直鬧到 VP,SVP 這個級別。每一次都是聽SRE的。

打通與產品團隊的反饋迴路

所有東西不都是百分之百穩定的,穩定性的提高要消耗成本,要增加更多的冗餘,更多的容量,甚至只能花錢解決。運維部門的任務就是提供這些資料和方案。比如搞三個9、四個9,要如何達到,這在投入和系統設計上有很大區別。這個部分公司裡沒有其他人可以提出,必須要由運維部門提出。如果沒有這個反饋迴路的話,你會發現大家都很痛苦,很多時候做出的決定都是違背自然規律的。我看過很多這樣的案例,上面拍腦門決定某個業務要100%穩定,完全不管下面怎麼搞,由於反饋迴路不存在或者這個反饋迴路的資訊流動不夠順暢,導致了這個東西最終實際做不好,這是SRE模型相當關鍵的一個地方。