高可用性系統在大眾點評的實踐與經驗
所謂高可用性指的是系統如何保證比較高的服務可用率,在出現故障時如何應對,包括及時發現、故障轉移、儘快從故障中恢復等等。本文主要以點評的交易系統的演進為主來描述如何做到高可用,並結合了一些自己的經驗。需要強調的是,高可用性只是一個結果,應該更多地關注迭代過程,關注業務發展。
可用性的理解
理解目標
業界高可用的目標是幾個9,對於每一個系統,要求是不一樣的。研發人員對所設計或者開發的系統,要知道使用者規模及使用場景,知道可用性的目標。
比如,5個9的目標對應的是全年故障5分鐘。
拆解目標
幾個9的目標比較抽象,需要對目標進行合理的分解,可以分解成如下兩個子目標。
頻率要低:減少出故障的次數
不出問題,一定是高可用的,但這是不可能的。系統越大、越複雜,只能儘量避免問題,通過系統設計、流程機制來減少出問題的概率。但如果經常出問題,後面恢復再快也是沒有用的。
時間要快:縮短故障的恢復時間
故障出現時,不是解決或者定位到具體問題,而是快速恢復是第一要務的,防止次生災害,問題擴大。這裡就要求要站在業務角度思考,而不僅是技術角度思考。
下面,我們就按這兩個子目標來分別闡述。
頻率要低:減少出故障的次數
設計:根據業務變化不斷進行迭代
以點評交易系統的演進過程為例。
幼兒時期:2012年前
使命:滿足業務要求,快速上線。
因為2011年要快速地把團購產品推向市場,臨時從各個團隊抽取的人才,大部分對.NET更熟悉,所以使用.NET進行了第一代的團購系統設計。畢竟滿足業務要求是第一的,還沒有機會遇到可用性等質量問題。考慮比較簡單,即使都掛了,量也比較小,出現問題,重啟、擴容、回滾就解決問題了。
系統架構如下圖所示。
少年時期:垂直拆分(2012-2013)
使命:研發效率&故障隔離。
當2012年在團單量從千到萬量級變化,使用者每日的下單量也到了萬級時候,需要考慮的是迭代速度、研發效率。垂直拆分,有助於保持小而美的團隊,研發效率才能更高。另外一方面也需要將各個業務相互隔離,比如商品首頁的展示、商品詳情頁的展示,訂單、支付流程的穩定性要求不一樣。前面可以快取,可以做靜態化來保證可用性,提供一些柔性體驗。後面支付系統做異地容災,比如我們除了南匯機房支付系統,在寶山機房也部署了,只是後來發現這個系統演進太快,沒有工具和機制保證雙機房更新,所以後來也不好使用了。
系統演進如下圖所示。服務垂直化了,但是資料沒有完整隔離開,服務之間還需要互相訪問非自己的資料。
青年時期:服務做小,不共享資料(2014-2015)
使命:支撐業務快速發展,提供高效、高可用的技術能力。
從2013年開始,Deal-service (商品系統)偶爾會因為某一次大流量(大促或者常規活動)而掛掉,每幾個月總有那麼一次,基本上可用性就在3個9徘徊。這裡訂單和支付系統很穩定,因為流量在商品詳情頁到訂單有一個轉化率,流量大了詳情頁就掛了,訂單也就沒有流量了。後來詳情頁的靜態化比較好了,能減少恢復的速度,能降級,但是Deal-service的各個系統依賴太深了,還是不能保證整體端到端的可用性。
所以2014年對Deal-service做了很大的重構,大系統做小,把商品詳情繫統拆成了無數小服務,比如庫存服務、價格服務、基礎資料服務等等。這下商品詳情頁的問題解決了,後面壓力就來了,訂單系統的壓力增大。2014年10月起,訂單系統、支付系統也啟動了全面微服務化,經過大約1年的實踐,訂單系統、促銷系統、支付系統這3個領域後面的服務總和都快上百個了,後面對應的資料庫20多個,這樣能支撐到每日訂單量百萬級。
業務的增長在應用服務層面是可以擴容的,但是最大的單點——資料庫是集中式的,這個階段我們主要是把應用的資料訪問在讀寫上分離,資料庫提供更多的從庫來解決讀的問題,但是寫入仍然是最大的瓶頸(MySQL的讀可以擴充套件,而寫入QPS也就小2萬)。
這時系統演變成如下圖所示。這個架構大約能支撐QPS 3000左右的訂單量。
成年時期:水平拆分(2015至今)
使命:系統要能支撐大規模的促銷活動,訂單系統能支撐每秒幾萬的QPS,每日上千萬的訂單量。
2015年的917吃貨節,流量最高峰,如果我們仍然是前面的技術架構,必然會掛掉。所以在917這個大促的前幾個月,我們就在訂單系統進行了架構升級和水平拆分,核心就是解決資料單點,把訂單表拆分成了1024張表,分佈在32個資料庫,每個庫32張表。這樣在可見的未來都不用太擔心了。
雖然資料層的問題解決了,但是我們還是有些單點,比如我們用的訊息佇列、網路、機房等。舉幾個我過去曾經遇到的不容易碰到的可用性問題:
服務的網路卡有一個壞了,沒有被監測到,後來發現另一個網路卡也壞了,這樣服務就掛了。
我們使用 cache的時候發現可用性在高峰期非常低,後來發現這個cache伺服器跟公司監控系統CAT伺服器在一個機櫃,高峰期的流量被CAT佔了一大半,業務的網路流量不夠了。
917大促的時候我們對訊息佇列這個依賴的通道能力評估出現了偏差,也沒有備份方案,所以造成了一小部分的延遲。
這個時期系統演進為下圖這樣:
未來:思路仍然是大系統做小,基礎通道做大,流量分塊
大系統做小,就是把複雜系統拆成單一職責系統,並從單機、主備、叢集、異地等架構方向擴充套件。
基礎通道做大就是把基礎通訊框架、頻寬等高速路做大。
流量分塊就是把使用者流量按照某種模型拆分,讓他們聚合在某一個服務叢集完成,閉環解決。
系統可能會演進為下圖這樣:
上面點評交易系統的發展幾個階段,只以業務系統的演進為例。除了這些還有CDN、DNS、網路、機房等各個時期遇到的不同的可用性問題,真實遇到過的就有:聯通的網路掛了,需要切換到電信;資料庫的電源被人踢掉了,等等。
易運營
高可用性的系統一定是可運營的。聽到運營,大家更多想到的是產品運營,其實技術也有運營——線上的質量、流程的運營,比如,整個系統上線後,是否方便切換流量,是否方便開關,是否方便擴充套件。這裡有幾個基本要求:
可限流
線上的流量永遠有想不到的情況,在這種情況下,系統的穩定吞吐能力就非常重要了,高併發的系統一般採取的策略是快速失敗機制,比如系統QPS能支撐5000,但是1萬的流量過來,我能保證持續的5000,其他5000我快速失敗,這樣很快1萬的流量就被消化掉了。比如917的支付系統就是採取了流量限制,如果超過某一個流量峰值,我們就自動返回“請稍後再試”等。
無狀態
應用系統要完全無狀態,運維才能隨便擴容、分配流量。
降級能力
降級能力是跟產品一起來看的,需要看降級後對使用者體驗的影響。簡單的比如:提示語是什麼。比如支付渠道,如果支付寶渠道掛了,我們掛了50% ,支付寶旁邊會自動出現一個提示,表示這個渠道可能不穩定,但是可以點選;當支付寶渠道掛了100% ,我們的按鈕變成灰色的,不能點選,但也會有提示,比如換其他支付渠道(剛剛微信支付還掛了,就又起作用了)。另一個案例,我們在917大促的時候對某些依賴方,比如誠信的校驗,這種如果判斷比較耗資源,又可控的情況下,可以通過開關直接關閉或者啟用。
可測試
無論架構多麼完美,驗證這一步必不可少,系統的可測試性就非常重要。
測試的目的要先預估流量的大小,比如某次大促,要跟產品、運營討論流量的來源、活動的力度,每一張頁面的,每一個按鈕的位置,都要進行較準確的預估。
此外還要測試叢集的能力。有很多同學在實施的時候總喜歡測試單臺,然後水平放大,給一個結論,但這不是很準確,要分析所有的流量在系統間流轉時候的比例。尤其對流量模型的測試(要注意高峰流量模型跟平常流量模型可能不一致)系統架構的容量測試,比如我們某一次大促的測試方法
從上到下評估流量,從下至上評估能力:發現一次訂單提交有20次資料庫訪問,讀寫比例高峰期是1:1,然後就跟進資料庫的能力倒推系統應該放入的流量,然後做好前端的非同步下單,讓整個流量平緩地下放到資料庫。
降低釋出風險
嚴格的釋出流程
目前點評的釋出都是開發自己負責,通過平臺自己完成的。上線的流程,釋出的常規流程模板如下:
灰度機制
伺服器釋出是分批的,按照10%、30%、50%、100%的釋出,開發人員通過觀察監控系統的曲線及系統的日誌,確定業務是否正常。
線上的流量灰度機制,重要功能上線能有按照某種流量灰度上線能力。
可回滾是標配,最好有最壞情況的預案。
時間要快:縮短故障的恢復時間
如果目標就要保證全年不出故障或者出了故障在5分鐘之內能解決,要對5分鐘進行充分的使用。5分鐘應該這樣拆解:1分鐘發現故障,3分鐘定位故障出現在哪個服務,再加上後面的恢復時間。就是整個時間的分解,目前我們系統大致能做到前面2步,離整體5個9的目標還有差距,因為恢復的速度跟架構的設計,資訊在開發、運維、DBA之間的溝通速度及工具能力,及處理問題人員的本身能力有關。
生命值:
持續關注線上執行情況
熟悉並感知系統變化,要快就要熟,熟能生巧,所以要關注線上運營情況。
瞭解應用所在的網路、伺服器效能、儲存、資料庫等系統指標。
能監控應用的執行狀態,熟悉應用自己的QPS、響應時間、可用性指標,並對依賴的上下游的流量情況同樣熟悉。
保證系統穩定吞吐
系統如果能做好流量控制、容錯,保證穩定的吞吐,能保證大部分場景的可用,也能很快地消化高峰流量,避免出現故障,產生流量的多次高峰。
故障時
快速的發現機制
告警的移動化
系統可用性的告警應該全部用微信、簡訊這種能保證找到人的通訊機制。
告警的實時化
目前我們只能做到1分鐘左右告警。
監控的視覺化
我們系統目前的要求是1分鐘發現故障,3分鐘定位故障。這就需要做好監控的視覺化,在所有關鍵service裡面的方法層面打點,然後做成監控曲線,不然3分鐘定位到具體是哪個地方出問題,比較困難。點評的監控系統CAT能很好的提供這些指標變化,我們系統在這些基礎上也做了一些更實時的能力,比如訂單系統QPS就是秒級的監控曲線。
有效的恢復機制
比如運維的四板斧:回滾、重啟、擴容、下伺服器。在系統不是很複雜、流量不是很高的情況下,這能解決問題,但大流量的時候就很難了,所以要更多地從流量控制、降級體驗方面下功夫。
幾點經驗
珍惜每次真實高峰流量,建立高峰期流量模型。
因為平常的壓力測試很難覆蓋到各種情況,而線上的真實流量能如實地反映出系統的瓶頸,能較真實地評估出應用、資料庫等在高峰期的表現。
珍惜每次線上故障覆盤,上一層樓看問題,下一層樓解決問題。
線上出問題後,要有一套方法論來分析,比如常見的“5W”,連續多問幾個為什麼,然後系統思考解決方案,再逐漸落地。
可用性不只是技術問題。
系統初期:以開發為主;
系統中期:開發+DBA+運維為主;
系統後期:技術+產品+運維+DBA。
系統較簡單、量較小時,開發同學能比較容易地定位問題並較容易解決問題。
當系統進入較複雜的中期時,就需要跟運維、資料庫的同學一起來看系統的瓶頸。
當系統進入複雜的後期時,系統在任何時候都要考慮不可用的時候如何提供柔性體驗,這就需要從產品角度來思考。
單點和釋出是可用性最大的敵人。
可用性要解決的核心問題就是單點,比如常見的手段:垂直拆分、水平拆分、灰度釋出;單機到主備、叢集、異地容災等等。
另外,系統釋出也是引起系統故障的關鍵點,比如常見的系統釋出、資料庫維護等其他引起系統結構變化的操作。
相關文章
- 高可用:美團點評智慧支付核心交易系統的可用性實踐
- 實踐解析:大眾點評賬號業務高可用進階之路
- 大眾點評點餐小程式開發經驗 - 概述
- 學習"大眾點評網的架構設計與實踐"架構
- 大眾點評點餐小程式開發經驗 - 釋出與推廣
- 大眾點評支付渠道閘道器係統的實踐之路
- 端智慧在大眾點評搜尋重排序的應用實踐排序
- 大眾點評搜尋相關性技術探索與實踐
- 大眾點評點餐小程式開發經驗 - 原始碼解析原始碼
- 大眾點評點餐小程式開發經驗 - 邏輯層
- 大眾點評點餐小程式開發經驗 - 檢視層
- MCI:移動持續整合在大眾點評的實踐
- 大眾點評點餐小程式開發經驗 – 資料採集
- 大眾點評點餐小程式開發經驗 - 資料採集
- HBase可用性分析與高可用實踐
- UAS:大眾點評使用者行為系統
- 大眾點評點餐小程式開發經驗 - 選單聯動設計
- 高可用性的HDFS—Hadoop分散式檔案系統深度實踐Hadoop分散式
- 大眾點評資訊流基於文字生成的創意優化實踐優化
- 大眾點評賬號業務高可用進階之路
- 大眾點評資訊流基於文字生成的創意最佳化實踐
- GitHub 的 MySQL 高可用性實踐分享GithubMySql
- 移動應用可用性測試的實踐經驗總結
- 大眾點評商家爬取
- 大眾點評搜尋基於知識圖譜的深度學習排序實踐深度學習排序
- Druid SQL和Security在美團點評的實踐UISQL
- Scrum與OKR融合實踐經驗分享ScrumOKR
- 同行程式碼評審過程中的實踐經驗行程
- 雲中SQL Server高可用性最佳實踐SQLServer
- 建立機器學習實戰系統的十大經驗教訓機器學習
- 如何設計一個高內聚低耦合的模組——MegEngine 中自定義 Op 系統的實踐經驗
- 推薦系統實踐自我評價
- root檔案系統的一點經驗(轉)
- 網易伏羲GDC分享:伏魔AI遊戲外掛防控系統在網易遊戲的實踐經驗AI遊戲
- 張翼:Spark SQL在攜程的實踐經驗分享!SparkSQL
- 在LINUX SUSE安裝PENTAHO的KETTLE實踐經驗Linux
- 在 Android 中實現 Redux 的一點經驗AndroidRedux
- 對單體系統優缺點評判到位:拆分Shopify單體工程的經驗分享