所謂高可用性指的是系統(tǒng)如何保證比較高的服務(wù)可用率,在出現(xiàn)故障時(shí)如何應(yīng)對(duì),包括及時(shí)發(fā)現(xiàn)、故障轉(zhuǎn)移、盡快從故障中恢復(fù)等等。本文主要以點(diǎn)評(píng)的交易 系統(tǒng)的演進(jìn)為主來(lái)描述如何做到高可用,并結(jié)合了一些自己的經(jīng)驗(yàn)。需要強(qiáng)調(diào)的是,高可用性只是一個(gè)結(jié)果,應(yīng)該更多地關(guān)注迭代過(guò)程,關(guān)注業(yè)務(wù)發(fā)展。
可用性的理解
理解目標(biāo)
業(yè)界高可用的目標(biāo)是幾個(gè)9,對(duì)于每一個(gè)系統(tǒng),要求是不一樣的。研發(fā)人員對(duì)所設(shè)計(jì)或者開發(fā)的系統(tǒng),要知道用戶規(guī)模及使用場(chǎng)景,知道可用性的目標(biāo)。
比如,5個(gè)9的目標(biāo)對(duì)應(yīng)的是全年故障5分鐘。
拆解目標(biāo)
幾個(gè)9的目標(biāo)比較抽象,需要對(duì)目標(biāo)進(jìn)行合理的分解,可以分解成如下兩個(gè)子目標(biāo)。
頻率要低:減少出故障的次數(shù)
不出問(wèn)題,一定是高可用的,但這是不可能的。系統(tǒng)越大、越復(fù)雜,只能盡量避免問(wèn)題,通過(guò)系統(tǒng)設(shè)計(jì)、流程機(jī)制來(lái)減少出問(wèn)題的概率。但如果經(jīng)常出問(wèn)題,后面恢復(fù)再快也是沒有用的。
時(shí)間要快:縮短故障的恢復(fù)時(shí)間
故障出現(xiàn)時(shí),不是解決或者定位到具體問(wèn)題,而是快速恢復(fù)是第一要?jiǎng)?wù)的,防止次生災(zāi)害,問(wèn)題擴(kuò)大。這里就要求要站在業(yè)務(wù)角度思考,而不僅是技術(shù)角度思考。
下面,我們就按這兩個(gè)子目標(biāo)來(lái)分別闡述。
頻率要低:減少出故障的次數(shù)
設(shè)計(jì):根據(jù)業(yè)務(wù)變化不斷進(jìn)行迭代
以點(diǎn)評(píng)交易系統(tǒng)的演進(jìn)過(guò)程為例。
幼兒時(shí)期:2012年前
使命:滿足業(yè)務(wù)要求,快速上線。
因?yàn)?011年要快速地把團(tuán)購(gòu)產(chǎn)品推向市場(chǎng),臨時(shí)從各個(gè)團(tuán)隊(duì)抽取的人才,大部分對(duì).NET更熟悉,所以使用.NET進(jìn)行了第一代的團(tuán)購(gòu)系統(tǒng)設(shè)計(jì)。畢 竟?jié)M足業(yè)務(wù)要求是第一的,還沒有機(jī)會(huì)遇到可用性等質(zhì)量問(wèn)題。考慮比較簡(jiǎn)單,即使都掛了,量也比較小,出現(xiàn)問(wèn)題,重啟、擴(kuò)容、回滾就解決問(wèn)題了。
系統(tǒng)架構(gòu)如下圖所示。
#FormatImgID_1#
少年時(shí)期:垂直拆分(2012-2013)
使命:研發(fā)效率&故障隔離。
當(dāng)2012年在團(tuán)單量從千到萬(wàn)量級(jí)變化,用戶每日的下單量也到了萬(wàn)級(jí)時(shí)候,需要考慮的是迭代速度、研發(fā)效率。垂直拆分,有助于保持小而美的團(tuán)隊(duì),研 發(fā)效率才能更高。另外一方面也需要將各個(gè)業(yè)務(wù)相互隔離,比如商品首頁(yè)的展示、商品詳情頁(yè)的展示,訂單、支付流程的穩(wěn)定性要求不一樣。前面可以緩存,可以做 靜態(tài)化來(lái)保證可用性,提供一些柔性體驗(yàn)。后面支付系統(tǒng)做異地容災(zāi),比如我們除了南匯機(jī)房支付系統(tǒng),在寶山機(jī)房也部署了,只是后來(lái)發(fā)現(xiàn)這個(gè)系統(tǒng)演進(jìn)太快,沒 有工具和機(jī)制保證雙機(jī)房更新,所以后來(lái)也不好使用了。
系統(tǒng)演進(jìn)如下圖所示。服務(wù)垂直化了,但是數(shù)據(jù)沒有完整隔離開,服務(wù)之間還需要互相訪問(wèn)非自己的數(shù)據(jù)。
青年時(shí)期:服務(wù)做小,不共享數(shù)據(jù)(2014-2015)
使命:支撐業(yè)務(wù)快速發(fā)展,提供高效、高可用的技術(shù)能力。
從2013年開始,Deal-service (商品系統(tǒng))偶爾會(huì)因?yàn)槟骋淮未罅髁?大促或者常規(guī)活動(dòng))而掛掉,每幾個(gè)月總有那么一次,基本上可用性就在3個(gè)9徘徊。這里訂單和支付系統(tǒng)很穩(wěn)定,因?yàn)榱?量在商品詳情頁(yè)到訂單有一個(gè)轉(zhuǎn)化率,流量大了詳情頁(yè)就掛了,訂單也就沒有流量了。后來(lái)詳情頁(yè)的靜態(tài)化比較好了,能減少恢復(fù)的速度,能降級(jí),但是Deal- service的各個(gè)系統(tǒng)依賴太深了,還是不能保證整體端到端的可用性。
所以2014年對(duì)Deal-service做了很大的重構(gòu),大系統(tǒng)做小,把商品詳情系統(tǒng)拆成了無(wú)數(shù)小服務(wù),比如庫(kù)存服務(wù)、價(jià)格服務(wù)、基礎(chǔ)數(shù)據(jù)服務(wù)等 等。這下商品詳情頁(yè)的問(wèn)題解決了,后面壓力就來(lái)了,訂單系統(tǒng)的壓力增大。2014年10月起,訂單系統(tǒng)、支付系統(tǒng)也啟動(dòng)了全面微服務(wù)化,經(jīng)過(guò)大約1年的實(shí) 踐,訂單系統(tǒng)、促銷系統(tǒng)、支付系統(tǒng)這3個(gè)領(lǐng)域后面的服務(wù)總和都快上百個(gè)了,后面對(duì)應(yīng)的數(shù)據(jù)庫(kù)20多個(gè),這樣能支撐到每日訂單量百萬(wàn)級(jí)。
業(yè)務(wù)的增長(zhǎng)在應(yīng)用服務(wù)層面是可以擴(kuò)容的,但是最大的單點(diǎn)——數(shù)據(jù)庫(kù)是集中式的,這個(gè)階段我們主要是把應(yīng)用的數(shù)據(jù)訪問(wèn)在讀寫上分離,數(shù)據(jù)庫(kù)提供更多的從庫(kù)來(lái)解決讀的問(wèn)題,但是寫入仍然是最大的瓶頸(MySQL的讀可以擴(kuò)展,而寫入QPS也就小2萬(wàn))。
這時(shí)系統(tǒng)演變成如下圖所示。這個(gè)架構(gòu)大約能支撐QPS 3000左右的訂單量。
成年時(shí)期:水平拆分(2015至今)
使命:系統(tǒng)要能支撐大規(guī)模的促銷活動(dòng),訂單系統(tǒng)能支撐每秒幾萬(wàn)的QPS,每日上千萬(wàn)的訂單量。
2015年的917吃貨節(jié),流量最高峰,如果我們?nèi)匀皇乔懊娴募夹g(shù)架構(gòu),必然會(huì)掛掉。所以在917這個(gè)大促的前幾個(gè)月,我們就在訂單系統(tǒng)進(jìn)行了架構(gòu) 升級(jí)和水平拆分,核心就是解決數(shù)據(jù)單點(diǎn),把訂單表拆分成了1024張表,分布在32個(gè)數(shù)據(jù)庫(kù),每個(gè)庫(kù)32張表。這樣在可見的未來(lái)都不用太擔(dān)心了。
雖然數(shù)據(jù)層的問(wèn)題解決了,但是我們還是有些單點(diǎn),比如我們用的消息隊(duì)列、網(wǎng)絡(luò)、機(jī)房等。舉幾個(gè)我過(guò)去曾經(jīng)遇到的不容易碰到的可用性問(wèn)題:
服務(wù)的網(wǎng)卡有一個(gè)壞了,沒有被監(jiān)測(cè)到,后來(lái)發(fā)現(xiàn)另一個(gè)網(wǎng)卡也壞了,這樣服務(wù)就掛了。
我們使用 cache的時(shí)候發(fā)現(xiàn)可用性在高峰期非常低,后來(lái)發(fā)現(xiàn)這個(gè)cache服務(wù)器跟公司監(jiān)控系統(tǒng)CAT服務(wù)器在一個(gè)機(jī)柜,高峰期的流量被CAT占了一大半,業(yè)務(wù)的網(wǎng)絡(luò)流量不夠了。
917大促的時(shí)候我們對(duì)消息隊(duì)列這個(gè)依賴的通道能力評(píng)估出現(xiàn)了偏差,也沒有備份方案,所以造成了一小部分的延遲。
這個(gè)時(shí)期系統(tǒng)演進(jìn)為下圖這樣:
未來(lái):思路仍然是大系統(tǒng)做小,基礎(chǔ)通道做大,流量分塊
大系統(tǒng)做小,就是把復(fù)雜系統(tǒng)拆成單一職責(zé)系統(tǒng),并從單機(jī)、主備、集群、異地等架構(gòu)方向擴(kuò)展。
基礎(chǔ)通道做大就是把基礎(chǔ)通信框架、帶寬等高速路做大。
流量分塊就是把用戶流量按照某種模型拆分,讓他們聚合在某一個(gè)服務(wù)集群完成,閉環(huán)解決。
系統(tǒng)可能會(huì)演進(jìn)為下圖這樣:
上面點(diǎn)評(píng)交易系統(tǒng)的發(fā)展幾個(gè)階段,只以業(yè)務(wù)系統(tǒng)的演進(jìn)為例。除了這些還有CDN、DNS、網(wǎng)絡(luò)、機(jī)房等各個(gè)時(shí)期遇到的不同的可用性問(wèn)題,真實(shí)遇到過(guò)的就有:聯(lián)通的網(wǎng)絡(luò)掛了,需要切換到電信;數(shù)據(jù)庫(kù)的電源被人踢掉了,等等。
易運(yùn)營(yíng)
高可用性的系統(tǒng)一定是可運(yùn)營(yíng)的。聽到運(yùn)營(yíng),大家更多想到的是產(chǎn)品運(yùn)營(yíng),其實(shí)技術(shù)也有運(yùn)營(yíng)——線上的質(zhì)量、流程的運(yùn)營(yíng),比如,整個(gè)系統(tǒng)上線后,是否方便切換流量,是否方便開關(guān),是否方便擴(kuò)展。這里有幾個(gè)基本要求:
可限流
線上的流量永遠(yuǎn)有想不到的情況,在這種情況下,系統(tǒng)的穩(wěn)定吞吐能力就非常重要了,高并發(fā)的系統(tǒng)一般采取的策略是快速失敗機(jī)制,比如系統(tǒng)QPS能支撐 5000,但是1萬(wàn)的流量過(guò)來(lái),我能保證持續(xù)的5000,其他5000我快速失敗,這樣很快1萬(wàn)的流量就被消化掉了。比如917的支付系統(tǒng)就是采取了流量 限制,如果超過(guò)某一個(gè)流量峰值,我們就自動(dòng)返回“請(qǐng)稍后再試”等。
無(wú)狀態(tài)
應(yīng)用系統(tǒng)要完全無(wú)狀態(tài),運(yùn)維才能隨便擴(kuò)容、分配流量。
降級(jí)能力
降級(jí)能力是跟產(chǎn)品一起來(lái)看的,需要看降級(jí)后對(duì)用戶體驗(yàn)的影響。簡(jiǎn)單的比如:提示語(yǔ)是什么。比如支付渠道,如果支付寶渠道掛了,我們掛了50% ,支付寶旁邊會(huì)自動(dòng)出現(xiàn)一個(gè)提示,表示這個(gè)渠道可能不穩(wěn)定,但是可以點(diǎn)擊;當(dāng)支付寶渠道掛了100% ,我們的按鈕變成灰色的,不能點(diǎn)擊,但也會(huì)有提示,比如換其他支付渠道(剛剛微信支付還掛了,就又起作用了)。另一個(gè)案例,我們?cè)?17大促的時(shí)候?qū)δ承?依賴方,比如誠(chéng)信的校驗(yàn),這種如果判斷比較耗資源,又可控的情況下,可以通過(guò)開關(guān)直接關(guān)閉或者啟用。
可測(cè)試
無(wú)論架構(gòu)多么完美,驗(yàn)證這一步必不可少,系統(tǒng)的可測(cè)試性就非常重要。
測(cè)試的目的要先預(yù)估流量的大小,比如某次大促,要跟產(chǎn)品、運(yùn)營(yíng)討論流量的來(lái)源、活動(dòng)的力度,每一張頁(yè)面的,每一個(gè)按鈕的位置,都要進(jìn)行較準(zhǔn)確的預(yù)估。
此外還要測(cè)試集群的能力。有很多同學(xué)在實(shí)施的時(shí)候總喜歡測(cè)試單臺(tái),然后水平放大,給一個(gè)結(jié)論,但這不是很準(zhǔn)確,要分析所有的流量在系統(tǒng)間流轉(zhuǎn)時(shí)候的 比例。尤其對(duì)流量模型的測(cè)試(要注意高峰流量模型跟平常流量模型可能不一致)系統(tǒng)架構(gòu)的容量測(cè)試,比如我們某一次大促的測(cè)試方法
從上到下評(píng)估流量,從下至上評(píng)估能力:發(fā)現(xiàn)一次訂單提交有20次數(shù)據(jù)庫(kù)訪問(wèn),讀寫比例高峰期是1:1,然后就跟進(jìn)數(shù)據(jù)庫(kù)的能力倒推系統(tǒng)應(yīng)該放入的流量,然后做好前端的異步下單,讓整個(gè)流量平緩地下放到數(shù)據(jù)庫(kù)。
降低發(fā)布風(fēng)險(xiǎn)
嚴(yán)格的發(fā)布流程
目前點(diǎn)評(píng)的發(fā)布都是開發(fā)自己負(fù)責(zé),通過(guò)平臺(tái)自己完成的。上線的流程,發(fā)布的常規(guī)流程模板如下:
灰度機(jī)制
服務(wù)器發(fā)布是分批的,按照10%、30%、50%、100%的發(fā)布,開發(fā)人員通過(guò)觀察監(jiān)控系統(tǒng)的曲線及系統(tǒng)的日志,確定業(yè)務(wù)是否正常。
線上的流量灰度機(jī)制,重要功能上線能有按照某種流量灰度上線能力。
可回滾是標(biāo)配,最好有最壞情況的預(yù)案。
時(shí)間要快:縮短故障的恢復(fù)時(shí)間
如果目標(biāo)就要保證全年不出故障或者出了故障在5分鐘之內(nèi)能解決,要對(duì)5分鐘進(jìn)行充分的使用。5分鐘應(yīng)該這樣拆解:1分鐘發(fā)現(xiàn)故障,3分鐘定位故障出 現(xiàn)在哪個(gè)服務(wù),再加上后面的恢復(fù)時(shí)間。就是整個(gè)時(shí)間的分解,目前我們系統(tǒng)大致能做到前面2步,離整體5個(gè)9的目標(biāo)還有差距,因?yàn)榛謴?fù)的速度跟架構(gòu)的設(shè)計(jì), 信息在開發(fā)、運(yùn)維、DBA之間的溝通速度及工具能力,及處理問(wèn)題人員的本身能力有關(guān)。
持續(xù)關(guān)注線上運(yùn)行情況
熟悉并感知系統(tǒng)變化,要快就要熟,熟能生巧,所以要關(guān)注線上運(yùn)營(yíng)情況。
了解應(yīng)用所在的網(wǎng)絡(luò)、服務(wù)器性能、存儲(chǔ)、數(shù)據(jù)庫(kù)等系統(tǒng)指標(biāo)。
能監(jiān)控應(yīng)用的執(zhí)行狀態(tài),熟悉應(yīng)用自己的QPS、響應(yīng)時(shí)間、可用性指標(biāo),并對(duì)依賴的上下游的流量情況同樣熟悉。
保證系統(tǒng)穩(wěn)定吞吐
系統(tǒng)如果能做好流量控制、容錯(cuò),保證穩(wěn)定的吞吐,能保證大部分場(chǎng)景的可用,也能很快地消化高峰流量,避免出現(xiàn)故障,產(chǎn)生流量的多次高峰。
故障時(shí)
快速的發(fā)現(xiàn)機(jī)制
告警的移動(dòng)化
系統(tǒng)可用性的告警應(yīng)該全部用微信、短信這種能保證找到人的通信機(jī)制。
告警的實(shí)時(shí)化
目前我們只能做到1分鐘左右告警。
監(jiān)控的可視化
我們系統(tǒng)目前的要求是1分鐘發(fā)現(xiàn)故障,3分鐘定位故障。這就需要做好監(jiān)控的可視化,在所有關(guān)鍵service里面的方法層面打點(diǎn),然后做成監(jiān)控曲 線,不然3分鐘定位到具體是哪個(gè)地方出問(wèn)題,比較困難。點(diǎn)評(píng)的監(jiān)控系統(tǒng)CAT能很好的提供這些指標(biāo)變化,我們系統(tǒng)在這些基礎(chǔ)上也做了一些更實(shí)時(shí)的能力,比 如訂單系統(tǒng)QPS就是秒級(jí)的監(jiān)控曲線。
有效的恢復(fù)機(jī)制
比如運(yùn)維的四板斧:回滾、重啟、擴(kuò)容、下服務(wù)器。在系統(tǒng)不是很復(fù)雜、流量不是很高的情況下,這能解決問(wèn)題,但大流量的時(shí)候就很難了,所以要更多地從流量控制、降級(jí)體驗(yàn)方面下功夫。
幾點(diǎn)經(jīng)驗(yàn)
珍惜每次真實(shí)高峰流量,建立高峰期流量模型。
因?yàn)槠匠5膲毫y(cè)試很難覆蓋到各種情況,而線上的真實(shí)流量能如實(shí)地反映出系統(tǒng)的瓶頸,能較真實(shí)地評(píng)估出應(yīng)用、數(shù)據(jù)庫(kù)等在高峰期的表現(xiàn)。
珍惜每次線上故障復(fù)盤,上一層樓看問(wèn)題,下一層樓解決問(wèn)題。
線上出問(wèn)題后,要有一套方法論來(lái)分析,比如常見的“5W”,連續(xù)多問(wèn)幾個(gè)為什么,然后系統(tǒng)思考解決方案,再逐漸落地。
可用性不只是技術(shù)問(wèn)題。
系統(tǒng)初期:以開發(fā)為主;
系統(tǒng)中期:開發(fā)+DBA+運(yùn)維為主;
系統(tǒng)后期:技術(shù)+產(chǎn)品+運(yùn)維+DBA。
系統(tǒng)較簡(jiǎn)單、量較小時(shí),開發(fā)同學(xué)能比較容易地定位問(wèn)題并較容易解決問(wèn)題。
當(dāng)系統(tǒng)進(jìn)入較復(fù)雜的中期時(shí),就需要跟運(yùn)維、數(shù)據(jù)庫(kù)的同學(xué)一起來(lái)看系統(tǒng)的瓶頸。
當(dāng)系統(tǒng)進(jìn)入復(fù)雜的后期時(shí),系統(tǒng)在任何時(shí)候都要考慮不可用的時(shí)候如何提供柔性體驗(yàn),這就需要從產(chǎn)品角度來(lái)思考。
單點(diǎn)和發(fā)布是可用性最大的敵人。
可用性要解決的核心問(wèn)題就是單點(diǎn),比如常見的手段:垂直拆分、水平拆分、灰度發(fā)布;單機(jī)到主備、集群、異地容災(zāi)等等。
另外,系統(tǒng)發(fā)布也是引起系統(tǒng)故障的關(guān)鍵點(diǎn),比如常見的系統(tǒng)發(fā)布、數(shù)據(jù)庫(kù)維護(hù)等其他引起系統(tǒng)結(jié)構(gòu)變化的操作。
分享到微信 ×
打開微信,點(diǎn)擊底部的“發(fā)現(xiàn)”,
使用“掃一掃”即可將網(wǎng)頁(yè)分享至朋友圈。