天天看點

阿裡搜尋事業部故障快速恢複實踐一、關于故障的幾種解決思路二、故障快速恢複的條件三、故障的快速發現---監控和報警系統四、故障的快速恢複---切流平台五、故障快速恢複的可持續性

這篇文章中,我們将讨論面對故障時,我們為什麼選擇快速切流這種機制。如果選擇快速切流,我們需要具備哪些條件,需要切流平台解決什麼樣的問題。最後,我們暢想故障快速恢複未來如何做的更好。

如何定義故障

我們一般從以下幾個次元來定義故障。一是影響的使用者數量,例如使用者投訴100個或者60%的使用者不可使用某功能。二是系統流量下降或者成交下跌,例如成交下跌6%。三是資損,例如廣告收入下跌5%。總之,故障是用來描述系統異常對使用者或者自身造成影響的一個量化名額。

故障一般分級别P4-P1,嚴重程度越來越高,故障到P2時就會全集團發周知資訊了。故障的定級時要考慮到業務自身的規模和疊代速度。故障級别定義超高時,會讓整個團隊風聲鶴唳經常忙于救火,進一步會影響釋出,最後會讓大家對于P1P2産生疲勞,不應該對新興業務定義過高的故障級别。

阿裡搜尋目前對于故障的定義中,有一條專門鼓勵快速恢複:5min内解決的故障,按照原等級降一級。

如何看待故障的定責

關于定責的原則,幾經修正,即使現在還有争議。之前實行過的有:誰觸發誰擔責;上遊接口變更未通知下遊造成的上遊承擔;下遊未按文檔或者約定使用上遊接口的下遊承擔;但是,上面的這些原則其實僅僅是為了更好的區分是誰的責任,而我們更應該回到本源,如何讓已經發生的問題驅動整個系統向好的方向行進。

舉個例子,A業務調用B業務接口,現在A因為變更調整了對下遊的壓力,把B壓垮了導緻整個系統流量跌為0。在實踐中這是個典型的例子,甚至現在讓大家去定責,不同的團隊也會有不同的結果。選擇A為主要責任可以說是A做了變更觸發的,也可以說A私自調整了流量未及時通知B。但是我們可以換一個思路,定責為A團隊會讓我們的系統自然地向更好的方向演進麼?B為什麼會在A的壓力大時徹底垮掉呢?B聲稱自己的服務能力為什麼在流量大時就不存在了呢?B為什麼沒有自我保護和自己限流呢?責任該給到誰會讓系統變得更好其實就較為清晰的能分辨了。

定責方面,在搜尋事業部的實踐中。沉澱有以下幾點,供大家參考。

出現core導緻的問題,不管觸發原因,誰寫的代碼誰的團隊承擔;

演習時,操作者不承擔責任,哪個系統挂掉,對應的團隊承擔責任;

一個小的觸發因素導緻一個超大的故障時,惡化的子產品承擔責任,而不是觸發者;

每個子產品有責任保護自己聲稱容量以内的流量和使用者,超出流量可以限流但是不能逾時,誰逾時誰的責任。

阿裡搜尋目前秉承的基本原則是:誰更應該從系統層面規避,誰的action更傾向于讓系統向好的方向演進,就更應該承擔責任。

如何看待故障的action

一個故障一般是由一連串的問題導緻,每個環節都出了問題才會導緻一個嚴重的故障。我們選擇做故障的action時有時候會有個傾向,就是加監控。這幾乎是個萬能的action,但是這背後其實有個隐含的依賴,就是人會處理這些報警,而且是及時處理。顯然這個隐含的依賴在很多時候是不成立的。

我們選擇故障的action時也應該考慮系統的自我保護,而不是加個監控了事。比如如何實作自動降級,自動限流。自動限流發生時,如何保證永遠都不逾時,自己聲稱的服務能力,即使再高的流量也垮不了(網卡未滿的情況下),這個單開專題讨論,不展開了。

解決故障的幾種思路

當一個故障發生時,當事人采用的第一個處理政策就是我們解決故障的思路。比如:

i. 直接去線上看日志,查到異常後嘗試進行恢複;

ii.收到報警後,切流恢複;

iii.嘗試讓系統自動定位故障在哪個地方,然後嘗試去恢複它;

第一種處理方法已經在實踐中越來越少的出現,因為現在大原則是先恢複後查問題,除非出現多個機房同時挂掉的情況,否則不是首選。第三種看起來也是一個不錯的方向,不過在實踐中這個方案的要求極高,需要系統具備:統一接口收集所有的系統名額和業務名額,統一接口收集所有的變更,給每個子產品定義何為異常,給子產品定義一個恢複政策。先不談其他恢複政策了,單單一個故障單元的自動替換就有不少系統做不到,是以這個政策目前看還太激進了。

第二種政策是目前交易和搜尋采用的核心政策,在收到報警之後,根據報警提示,快速把流量切到服務正常的機房。從實踐上看,好一點的可以做到5min以内恢複,差一點的10min也足夠了。

但是第二種政策也是有條件的,下面一節讨論快速切流的條件。

多機房和機房間延遲

如果選擇快速切流作為快速恢複的手段,那麼就要首先考慮切流的條件。其中就有多機房(多叢集)的要求。搜尋目前采用的方式是三地三機房部署,既可以做異地容災,也可以做故障時切流。

切流最好的方式,是使用者的通路直接去另外的機房。但是并不是所有的業務都有能力控制上遊的入口流量配置設定。同時也不能因為整條鍊路上任意子產品的故障,就能要求導購或者交易整體切流。是以,業務自身多機房部署和切流能力就是必須的。

如果不是最入口的切流,那上遊過來的流量就會産生跨機房通路。跨機房的延遲就必須考慮在内,目前國内三地的主力機房A---B ping值約30ms,B---C ping值約25ms,A---C ping值約37ms。如果業務自身的服務latency遠遠小于該值那麼切流恢複的條件就是不具備的。有時我們的系統有很多個層次,比如主搜尋有java層---sp層---ha3引擎---ranking這幾個層次。

我們切流時應該盡量選擇自身能夠控制的最上遊子產品,因為越往下層latency越低,跨機房的latency增加影響也就越大。

容量限制

切流的第二個條件是容量。不能切到其他機房(叢集)後,原來ok的機房也被壓垮。那這就要求其他機房,在切流子產品及以下所有子產品的容量,都能保證剩餘機房是足夠支援高峰期的。這是容量上的限制。

這裡所指的容量,一般是指業務可以忍受延遲範圍内的最高通路量。

上面說的容量要求,其實是一種最初始的限制。自動降級和自動限流可以突破這個限制。自動降級指的是:系統在超出自身正常的服務容量時,采取的一種自我保護措施。自動降級一般是業務邏輯的自動更改,例如當搜尋引擎的壓力過大時,自動把精排數量減少。自動降級會犧牲一部分效果,但是能夠自動的瞬間的提升服務能力,可以抵禦突發的流量增加給系統帶來的沖擊。

當流量繼續增加,即使自動降級也無法抵禦時,應該觸發自動限流措施。自動限流指的是丢棄部分超出自身服務能力的請求,同時保證已經接收的請求正常傳回。自動限流是非常時期采取的非常手段,不止會影響效果,更會使得部分使用者的請求無結果。但這是無奈之舉,是大家一起死還是保留一部分服務能力,選擇肯定是後者。

如上,當實作了自動降級和自動限流之後,切流這個流量突變的操作就變成了一個相對安全的操作。假設AB兩個機房容量各為60%,這時如果切流A--->B那麼B機房流量會超出正常容量。B機房發生降級後,服務能力立刻提升50%,切流操作後B機房效果下降。但是可以成功支援住因為故障從A機房切過來的流量。

真實情況可能比上面的更複雜,比如考慮到超線程的影響,cpu運作到60%以上時性能會迅速惡化。三機房甚至更多機房的建設,可以明顯提高雙機房容災時,允許的機房内運作水位。例如搜尋三機房建設允許機房内水位運作到40%。

監控的快速采集

資料名額的采集有兩種方式,一種是基于日志的采集,這種方式依賴于系統打日志,然後定時器去觸發采集動作。另一種是種下agent,agent提供标準的接口,每個應用向标準接口吐出标準格式的資料,這個資料是本地非持久化的,通過記憶體直接傳輸到遠端存儲。

目前搜尋使用烽火台作為與kmonitor對接的報警系統,烽火台支援metric次元的報警,支援多個metric之間互相運算結果的報警方式。

目前集團的xflush或者alimonitor的監控和報警,均基于aone産品樹和armory分組。對于ip漂移、分組移動都是不能容忍的。比如一個分組下面有100個容器,現在你擴容20個容器,那麼很快在xflush上面會看見一個小坑,需要一段時間去同步ip清單。如果是持續不斷的ip漂移(大混部之後的常态),那監控和報警有時會誤報。agent直接對接metric,metric不同次元的标簽,不依賴分組和應用,可以解決該問題,這是大混部之後的趨勢。

統一的切流接口是切流平台的條件,這裡的統一不一定是一個,但是要有規範。比如現在搜尋這邊的切流平台基本上統一到:vipserver接口、tpp推薦切流接口和dns切流接口。

實驗鍊路可能不是一個普遍的問題,但是在搜尋和廣告都存在。實驗田是用來分桶驗證算法效果的叢集,試驗田的流量一般是在java接入層通過使用者id的hash做分桶,然後選擇某些桶的流量進入試驗田。之是以單拎出來是因為它的切流措施是特殊而且容易遺漏和出問題的。

一般試驗田考慮到成本問題,隻在一個機房部署。當該機房出故障時,出了主叢集外試驗田也應該随之切走。

在進行vipserver的切流時,如果僅僅是禁用掉某個機房下面所有的ip,進而達到流量切到其他機房目的。那麼有一個潛在的風險就是,如果出現機房的内的iplist,在切流期間發生了變化,那麼就會有流量重新進入到故障機房,這是絕對不能容忍的。

之是以提這點,是因為集團現在都在上排程器和容器化。單個損壞的節點會自動進行替換,替換的機器有新的ip,這個新ip會自動挂載到vipserver上。這時就和切流發生沖突了。解決的方案當然也很簡單,vipserver現在提供一種disable機房的接口,調用這個接口後。單個ip發生漂移并不會影響整個機房的流量被切走。

開發同學們即使有值班機制,也有了手機端切流的快速處理能力。但是仍然不能保證24H線上。處理速度維持在5min已經是極限了。下一步需要把報警标準化和簡單化,做到能夠讓GOC同學處理,GOC托管。

人工演練需要專人值守,專人處理。時間一長,非常容易懈怠。實際上之前确實這樣做的,但是專人搞演習是不靠譜的,對個人來說一直會有其他重要的事情會優先級高于演習。幾次嘗試之後,放棄了持續走人工演習的道路。

所謂自動演練,其實也沒有那麼複雜。理念其實很簡單,就是每個子系統每周定時演練一次,由人工觸發變成定時器觸發。定時器是一個倒計時,如果有緊急情況就去重置這個定時器,否則就會觸發演習動作。自動演練成熟的條件,就是所有的演習科目都人工演練過。自動演練目前處于開發階段,很快就會實施。

上面提到了自愈系統,這是一種故障快速恢複的終極形态。雖然我們現在的條件還不成熟,但這是可以想象的未來。這裡的自愈系統并不是指簡單的故障機替換、重新開機、清理日志這種操作。而是指的更大規模的隔離、切流、修複、恢複于一體的系統。

上面,我們從為什麼選擇快速恢複作為處理故障的首選。快速恢複依賴快速監控資料收集和快速的報警,快速恢複還依賴統一便捷的切流平台。本文最後,和大家讨論了快速恢複的下一步該怎麼走。

 ----------------------------