阿里雙 11 高可用架構演進之路

阿里巴巴平臺的業務規模在過去的 8 年呈指數級增長,給雙 11 所帶來的技術挑戰是世界性的,特別是如何在零點峯值到來時確保系統的穩定性。零點技術挑戰的本質是用有限的成本去實現最大化的集羣整體吞吐能力和最佳的用戶體驗,並取得二者之間的平衡。阿里在解決這些問題的時候沒有參考和借鑑的對象,只能自我創新。阿里技術團隊在 8 年雙 11 歷練中沉澱了很多技術產品,其中高可用方面的中間件技術,經歷了幾代架構的演進和優化越來越成熟,且在阿里雙 11 技術保障中起到的作用越來越大。丁宇從擴展性、線上的容量規劃、成本增速過快、精細化運行控制和線上穩定性治理等方面進行了闡述。

對於未來的挑戰,丁宇則認爲還有很多可以優化的地方,他歸納爲精細化、數據化及智能化三方面,及從容量確定性到資源的確定性;更加精細化的分析和預測流量模型及業務模型;技術變量的採集、分析、預測,通過數據分析驅動,自主決策處理等,最終在用戶體驗、成本控制和最大系統吞吐能力之間找到新的平衡點。

演講全文:

丁宇:大家好!我今天演講的主題是《零點之戰 -- 阿里雙 11 高可用架構演進之路》。大家知道,規模和場景是驅動技術發展的關鍵要素。阿里做了 8 年雙 11,業務規模有上百倍的增長,系統的複雜度和大促支撐難度更是以指數級攀升。隨着規模的增加,技術挑戰也非常不一樣,後面會展開講。這是一個世界級的場景,雙 11 最難的就是保障零點峯值的穩定性,我們把它當做一場戰爭來打,是一場不能輸的戰爭。面對世界級的難題,在業界沒有什麼可以參考和借鑑的對象,所以我們都是自主創新,沉澱了很多技術產品,高可用性的產品,經歷了幾代的架構演進,今天我會選取一部分跟大家做個交流。下面是我的個人介紹,和聯繫方式。

圖片

我們看一下整個雙 11 的技術挑戰是什麼,大家知道做雙 11 非常難, 但是究竟難在什麼地方?阿里內部有一句話: 雙 11 是業務的狂歡、技術的盛宴。阿里做了 8 年雙 11,這 8 年見證了電商業務的飛速發展,我們看一下業務指標變化。雙 11 交易額從 2009 年的 5.9 億到 2016 年,半個月以前的雙 11 交易額達到 1207 億,實現了 200 倍的增長。交易峯值從 2009 年的 400 筆每秒,到 2016 年 17.5 萬筆每秒,增長了 400 多倍。系統規模也有幾十倍、上百倍的增長。

圖片

在這一塊麪臨着什麼問題?首先面臨的是系統擴展性的問題,規模增長了數百倍,系統是不是能水平擴展以支撐數百倍的增長?這是我們面臨的首要難題。

雙 11 零點技術挑戰的本質是什麼?是用較低的成本去實現最大化的吞吐量和最佳的用戶體驗,三者取得一個平衡,用合理的代價來解決零點峯值, 支持好業務的狂歡,保證業務系統平穩運行。如果不限成本做這件事,難度會降低非常多。我們用有限成本來做這件事就會面臨一個問題,集羣規模、機器數、機房資源都是固定的,怎麼能把資源最合理的分配下去?假設有 500 個系統,要一起來支持雙 11,要做一個非常極致的容量規劃,把硬件資源能夠非常均勻地分配給每一個應用,讓整個集羣整個技術鏈條上沒有瓶頸,這就是容量領域最大的挑戰。因爲如果有一個地方存在短板,整個系統就沒法做到最大化吞吐量,所以要求有一個極致的容量規劃。

雙 11 的不確定性來自於什麼呢?還是來自於所有技術變量的疊加,如果業務不變,系統架構不變,技術也不升級,那難度會越來越小。但是所有事情都在變,好多變量,比如說用戶的流量會發生很大的變化,有很大的增量,峯值流量的構成、還有系統架構的變化會帶來很多不確定。流量的組成部分有哪些用戶來源,哪些業務模型會讓峯值的流量和壓力不同。包括 CPU 利用率,這些會影響到整體,因爲整個系統是在非常高的水位情況下運行的,又要運行平穩、整體全鏈條沒有短板,所以對線上要實現非常精細化的運行控制,還要有很強大的穩定性治理能力,這又是一個挑戰。

零點峯值對我們來說有什麼意義?這個意義非常巨大。它可以讓技術實現能力有個推動力,推動架構優化,加速技術演進和沉澱,催生技術創新,所以雙 11 也是技術的盛宴。

針對這幾個挑戰,我今天分成幾個部分:如何解決業務增長情況下擴展性的問題、如何解決線上容量規劃的問題、如何解決成本增速很快的問題、如何做精細化的運行控制、如何治理線上穩定性。

先講一下淘寶架構的發展背景,2007—2008 年這兩年,是從集中式架構快速演變爲分佈式的架構。大家已經非常熟悉這套架構,現在一般的互聯網應用,互聯網系統都會採用這樣的分層架構,業務上分層,通過分佈式中間件進行遠程消息傳遞、遠程服務調用,中間提供一層共享中心,把公共業務邏輯抽象成平臺,抽象成服務中心,不直接對用戶暴露接口,提供一種服務能力,中間會有緩存,底層有存儲集羣,這是非常常見的架構,在 2008 年整個架構演變到這個程度,到現在爲止架構也沒有發生太大變化。

圖片

隨着場景的遞增、體量的激增帶來了很多別的問題,是這套架構不能解決的,後面會逐步展開。在這個演變的過程中,我們沉澱了大量的中間件技術產品,這裏就像一個大廈,系統之間的交互,分佈式環境下的交互,包括一致性協調、負載均衡工作都是由中間件完成的,中間件就相當於大廈的框架結構和管道,中間件的沉澱對後面的架構演進打了非常好的基礎。

在這個架構改造完成後,早期雙 11 的規模增長問題還沒有那麼明顯,我們面臨着很多其他問題,其中就包括系統可用性。因爲我們由 10 個系統快速拆成 100 個系統,然後分層,水平拆分、垂直切分,面臨着治理的問題。以前出現問題知道是一個系統導致的,可以快速回滾變更恢復,現在是 100 個系統,很難定位問題根源在哪裏。好多系統發佈、變更了,也沒辦法快速恢復,失去了先恢復後定位的能力,這是我們面臨的挑戰。當時存儲層還有很多 IOE 技術組件,從 2009 年開始去 IOE,存儲這一層也把它升級成可以水平擴展的架構。

圖片

那個時候整個機房會遇到很多不穩定的情況,不知道有多少人當年也在做同樣的事情,網絡、電力都有不穩定的情況,很普遍,我們做 了同城容災和異地冷備的架構迭代。同城兩個機房,各承擔 50% 的流量,數據庫也放在兩邊一主一備。一個機房出問題的時候可以進行數據庫、流量的切換,這是同城容災的方案。

這套架構逐漸在雙 11 碰到了很多問題,當規模增長的時候,對機房體量要求越來越大,要有很大的規模。分佈式架構下,比如說 A 集羣要對 B 集羣有服務依賴調用,規模都是 5 千臺,大家知道負載均衡的機制,需要建立連接。五千對五千,連接數在超級機房下是一個很大的挑戰。數據庫也一樣,你規模達到了一萬臺,每臺都要建立連接。單機房無法承載業務系統規模的增量,擴展性是在中間件這一層受到限制。

IDC 的資源也存在限制,一個城市沒有辦法支撐我們的體量,這是物理限制。包括本地容災問題,颱風、電力導致問題,告訴你 2 小時後就拉閘限電,技術沒準備好切換,業務就會受損。還有國際化部署的問題,需要把業務集羣部署出去。這些挑戰要求我們由同城走到異地。

我們去觀察整個阿里電商的業務,它的數據模型,有這樣一個方案。建設異地單元機房,在地域上可以相互容災,異地大量調用的時延問題是一個巨大挑戰。大家可以算一下,北京到上海調用一個 RTT 需要多少毫秒,一次調用可以接受,如果每個請求調用 500 次是絕對不能接受的。所以單元內要做調用封閉,必須在單元內完成所有的業務請求交互。同時要按用戶的維度去切分單元流量,這樣就可以實現水平擴展,什麼規則的用戶在哪個單元來處理他的業務請求。

我們分析整個阿里業務模型,分爲買家數據、賣家數據,發現賣家數據體量適中,而且更新不那麼頻繁。買家數據會創建很多交易訂單,數據規模和訪問量很大,比賣家要大一個數量級。要保持每個單元的封閉,需要去切分買家集合,賣家數據集合小可以同步到各個單元,選擇這樣一個方案。在數據層實現數據同步,達到一致性,保證業務在單元內的封閉調用。

圖片做完就是現在這麼一個架構。可以按用戶任意維度進行路由,運用不同規則路由到不同的單元機房,在單元內實現業務的閉環, 解決了請求時延的問題。後續擴展性就很好做了,容量不夠再建一個單元,因爲單元內閉環,所以可以建到更遠的地方去,體量就不再是限制了。

每一層,每個單元都有完整的部署,當然也會有跨單元請求的情況存在,有一些服務調用、消息同步,包括底層的數據同步一直都在做,而且量很大,要保證每個單元的數據合法、一致,完成業務全鏈條的封閉。

這套架構對我們有什麼幫助?首先它消除了 IDC 資源單點和容量單點的問題,容量瓶頸解決了,不會受地域的限制。也解決了異地容災的問題,可以快速建一個單元,快速把流量切走。當一個地域性問題出現的時候,可以快速把流量切走,這個問題就恢復了,等地域性問題恢復,流量再切回來,日常可用性的保障就有了很好的提升。容量規劃這件事也因此簡化了, 一個單元有固定的處理能力。然後可以快速複製一個單元,可以小體量驗證,逐個單元批量複製,整體容量和擴展性就變得簡單了。同時提升了可運維性,單元可以快速拉起、下線、遷移。這個問題的解決爲後續的架構演進,打下了很好的基礎。

看一下容量規劃是怎麼做的,這也經歷了幾個階段的演進。一般來講,要做容量一定要先掌握應用性能基線,比方說 500 個系統,每一個系統的性能基線都要掌握。最開始的時候,在線下開始做,使用很多常見的壓測工具。當然受限於環境因素,線下環境很難打造一個完備的、跟線上非常相似的環境。我們通過壓側得到這個應用的性能基線,然後準備一個容量模型,通過基線吞吐量去計算將來有多大流量,在保持一定水位的前提下,可以知道在雙 11 的時候應用怎麼做容量規劃。

圖片

這個計算模型好幾年都沒有變過,一直在變的一個事情是,如何測試這個應用的基線吞吐量能力。經歷了幾個階段,線下是一個階段,我們發現線下非常不準,然後又走到線上。如何使用線上環境不影響用戶?得到一個高水位下的吞吐能力表現。採用線上引流的方式,無論存儲層、服務層還是 Web 應用這一層,都是用線上引流,依賴於中間件,自研的中間件負載均衡,還有反向代理都有流量代理的能力。如果有一百臺服務器,把其中 80 臺的流量一點一點引到某 10 臺上去,看在不同的流量壓力下,系統負載的增加,用戶響應時間的變化,三者之間的關係,把這張圖畫出來,這就比線下做這件事情精準度高很多,也逼近想要的結果,這就是我們線上壓測的架構。我們評估出來基線能力然後做容量規劃,這是一個階段。

這個階段很快就遇到了挑戰,大家知道,早年在雙 11 買東西時會遇到有一些大的、小的問題,跟容量規劃不準有很大的關係。容量規劃的目的是評估用戶登陸、添加購物車、購買整個鏈條如何合理分配資源。剛纔說一個應用雙 11 加多少機器,根據對雙 11 業務的理解來分配,這樣做規劃。這種流量規劃是不是合理的?我們發現差距還是蠻大的,真正雙 11 零點峯值的實際流量,與我們的規劃差距比較大。

圖片

500 多個核心繫統,技術鏈條長、業務入口多、邏輯複雜,如果人來梳理難免會有各種各樣的偏差。整個鏈條上瓶頸點比較多,因爲沒有驗證過,問題會比較多。無法提前發現問題,雙 11 峯值真正來的時候發現已經晚了,需要應急措施來處理這些問題。這個規劃方法是堆積木的方法,拼出來整個集羣配比,人的判斷在裏面起了很大的作用,往往都是不靠譜的。我們發現做容量規劃不應該是一個一個應用系統去看,應該是一個業務鏈條整體去看。

如圖所示,整個線上關係比這個複雜得多,這只是一個樣例,上游調用方有十幾二十個,下游依賴方有十幾二十個,每個調用方輕微的差異變化就會對這個集羣產生疊加效應,變化會放大,所以這個非常不準。我們缺乏驗證整個鏈條實際承載能力的手段,這是遇到的很大的挑戰。

我們提出需要一個驗證方案,雙 11 是屬於有限場景,真正流量的衝擊只在幾個流量入口,可能是 20 個流量入口,整個洪峯流量關係是可以梳理出來的,每個鏈條一起來驗證它的容量是不是符合預期,有這樣一個方案設計。我們希望在線上來做,用大規模的流量去壓測,從 IDC 到網絡、中間件、應用、緩存、數據庫,所有基礎設施能夠用同樣的流量模型來驗證,這也要求在線上做,而且要做海量請求,跟雙 11 同樣的流量驗證整個集羣的實際能力。

圖片

    要自定義一個工具,業界所有的流量工具都滿足不了規模的需求,所以要自己創造。同時業務模型和流量模型要非常精準,跟雙 11 非常像,基於線上數據、測試數據結合構造一套特殊模型,大體量、大規模、非常逼真。如果字段是空的、假的,執行過程中對字段計算的消耗就是受限的、是不真實的,所以要達到非常嚴苛的擬真度。還要求在線上做讀、寫、創建、支付操作,同時絕對不能影響用戶,壓測數據、正常數據不能混在一起,用戶要做到無感知。要把系統所有瓶頸暴露出來,我們設計了這樣一個方案。

這裏大量利用了之前沉澱的中間件體系。我們構造了一個分佈式流量引擎,把它部署在全國阿里的 CDN 上,阿里 CDN 規模非常大,這滿足了發出大流量的要求,可以反壓阿里機房,產生巨大的壓力,一秒達到上千萬的 QPS。在數據模型的構造上花了很大心思,每年會不斷迭代,讓它更加逼近真實。同時對用戶的流量進行了很好的數據化分析,真正模擬雙 11 當時的用戶流量,結合這份數據推送到壓測引擎裏,然後從遠端發起壓力。

圖片

整個鏈條覆蓋很長,和客戶端一樣建立鏈接,整個覆蓋鏈條跟用戶訪問基本上是一樣的。做的是線程級隔離,每個線程處理的可能是測試請求,也可能是正常用戶請求,請求間互相無感知,數據不會共享。同時對數據存儲層進行了隔離,也不會做全網的業務,只覆蓋雙 11 最重要的業務場景,這樣風險比較可控,暴露問題也更加精準有針對性。

全鏈路壓測是一個劃時代的容量規劃技術,壓測演練過程中發現很多瓶頸,無論是容量調配問題、性能問題還是隱藏 bug。併發的問題只有在大流量下才會暴露,小流量的線下測試,受限場景下是驗不出來的,所以用這套方案,容量也可以調整,問題也可以暴露,我們每年用這個壓測方案可以發現上千個問題,很多問題是非常致命的,如果雙 11 的時候爆發都是不能承受的。

這個方案有什麼意義,它打破了對於不可預知技術風險的控制能力,加速技術的進化。怎麼理解?我們在短時間內可以大膽創新,大膽上新技術,更加激進。因爲有一套保底方案,無論做多少創新,可以做到幾個月升級一次架構,新技術幾個月推到全網。因爲雙 11 要的是容量確定性, 比如說要準備 17.5 萬的能力,什麼技術都可以嘗試,最後通過線上演練,大流量全鏈路壓測,看能不能達到 17.5 萬。能達到技術是過關的,整體能力也是過關的,所以加速了技術的進化。

它能做到主動發現問題而不是被動等待,如果零點發現了再應急處理,應急處理往往是很被動的,而且容易忙中出錯。應急出現的問題往往是預期不到,沒有很好的手段去解決。比如說出現了數據問題, 寫個腳本對數據做後臺更新,這可能會產生更悲劇的事情,所以要減少應急的情況,儘量做到全都是確定的,有什麼大招都是測試驗證過的,這也是我們的經驗。這種壓測演練方式爲我們穩定性的確定性打下了堅實的基礎。

看一下成本優化,這是個很大的話題,我們可以做性能優化降低成本,但雙 11 這個體量來講,做單一系統優化對全局有多大幫助要打個問號,不是說它沒有用。性能優化的關鍵還是在於找到瓶頸,對瓶頸進行優化,這個效果是最好的。鬍子眉毛一把抓,500 個系統都優化 20%,最後不一定是整體水平提升 20%,性能優化和降低成本也有一定的關係, 然後可以進行架構整合,從架構層面做優化。通過分析,我們發現還有更好的方式。

圖片

上面的紅線是日常處理能力,這是截取的某一段時間,幾個月內的峯值情況。大家會發現,日常情況下很多小活動,日常能力是能夠處理的,大活動日常能力是不能處理的。爲了一個活動增加了一批機器資源,活動過後很長時間機器是沒法利用起來的,要長期分攤這個成本,對雙 11 來講就是這樣。爲了雙 11 這一天增加了大量成本,過後一年都會有資源利用率不高的情況,很可怕的浪費,因爲體量比較大,低效運行對成本影響很大。需要找到一個能夠幫助解決短時間內要很多資源,長時間又都不需要的問題,阿里雲的彈性能力就是最好的方案,所以我們選擇阿里雲的基礎設施,做混合雲彈性架構。它可以降低資源保有時間,大促就一天,剩下時間就把資源歸還給雲,這個方案大幅降低了大促成本。我們做的混合雲架構支撐雙 11,規模是全球最大的。使用雲的效率高不高,資源保有時間長短很大程度上取決於運維能力,包括怎麼跟業務集成,也做了很多運維能力的升級。包括 8 小時在雲機房拉起一個站點,就是前面講的 8 小時建一個單元,成本節約。以前是 20 天,現在提升到 1 天,對成本優化的效果是非常明顯的。

買了一批資源建起一個站點,還需要把資源調勻,通過全鏈壓測,3 小時可以把整個機房甚至全部機房資源調勻,提升效率也是降低成本的手段。同時實施了全面 Docker 化,拉平異構平臺的運維成本,用一年的時間把核心系統全部 Docker 化來支撐雙 11。做這種技術升級,是需要全鏈壓測驗證的,不然也不會這麼快完成,現在阿里有幾十萬的 Docker 容器跑在線上。

接下來看一下運行控制,系統容量已經調勻,有了最大吞吐能力,但是用戶熱情很誇張,超出想象。超出整個集羣處理能力的流量,需要把它擋在外面,如果放進來的話,整個集羣就一起宕掉了,一個請求都處理不了,整體癱瘓,這時必須做限流保護和有損服務,放進來的流量好好處理,沒有放進來的,等一會兒刷一下也會進來,這是通用做法。

圖片

我們通過訪問請求數做限制,也可以通過應用負載做限制,也可以通過線程併發數。調用下游,當下遊產生問題負載變高時,線程數會增加,這時就要對下游進行降級,要識別哪些系統可以被降級,系統自身可以自動完成降級,不會對核心業務產生大的影響,這是要事先識別的。通過識別哪些業務可以被降級,通過限流框架降掉這些場景。當發現流量大到無法處理時,就限制一些擋在外面,每一層都有限制,包括 web 接入層、應用層、服務層。整體原則是處理不了就別放進來,放進來的就是處理得了的,外面入口收緊一點,裏面處理放鬆一點,有很多自我保護手段。

圖片

再看一下流量調度,整個系統在高水位運行的情況下很容易產生波動,有一個集羣。平均來看整體水位 70%,但是有幾臺可能瀕臨崩潰了,這很常見。比如說有一個比較大的計算,路由到某臺機器,是經常碰到的。會發現很多流量也會同時路由到這臺服務器,這些流量都會受到影響。根據實時探測,通過現有的一些基礎能力、負載均衡進行流量調度,把有問題的機器歸併在一起降權,有問題的計算就被隔離了,路由的流量就到了正常機器,分佈式系統可以實現自我隔離和恢復,實現了流量的調度。關注局部用戶體驗,只要流量放進來,都要給一個比較好的處理和響應,提升整體的可用性和體驗。

圖片

這是開關和預案,對雙 11 來說非常重要。開關是系統後門,提供一套標準化的系統後門,可以讓應用不改代碼,通過配置改變行爲, 雙 11 我們準備了非常多的開關。光有開關還不夠,有些業務鏈條需要降級,可能一個鏈條上 20 個系統都要操作一些開關,才能把一個業務完整降級,在複雜系統上經常會遇到這樣的場景。我們實現了一套預案體系,保證一系列的開關能有序、完整的被執行,而且每一臺服務器都要執行到位,保證一致性、完整性。

一個經驗教訓就是雙 11 的時候千萬別執行沒有測試過的開關,往往會出問題。雙 11 今天體量很大,有數以千計的預案,還是對每一個預案進行測試,保證每一個開關、預案執行下去都是滿足期望的。

圖片

下面說一下穩定性治理。當系統複雜到一定程度,沒有一個人能掌握整個系統架構,只能用中間件能力來識別架構複雜度,理清關係。通過中間件的通道能力跟蹤整個調用鏈條,推動架構梳理,整理出依賴關係,對海量調用進行統計,得到各個系統的穩定性指標,這都是從數據中挖掘的。比如說調用層次、響應時間,哪裏阻斷了會影響業務,哪裏阻斷了不會影響業務,都是被挖掘出來的。同時會結合業務測試用例看哪些鏈條可以被降級,哪些不可以降級,有些降下來主業務就不顯示了。技術同學會對弱依賴做業務容錯,強依賴要保證系統不能掛,穩定性治理非常關鍵。

圖片

做了這麼多年雙 11,未來會有哪些挑戰?我們希望能做到精細化、數據化、智能化的雙 11,從容量確定性到資源確定性,哪些應用放在一起,什麼樣的配置放在一起會讓整體集羣達到最佳狀態,後續希望做到每一臺物理機的內核怎麼分配,仍然知道如何匹配達到最佳狀態,進入到微觀的層面,目的還是一樣,讓整體集羣全局沒有瓶頸,做到非常精細化。技術有很多變量,疊加會產生風險,所以要精細分析、預測,得出逼近真實的流量數據模型。我們希望做到智能化的雙 11,還是對這些變量,要通過數據分析去自我決策。根據多年的積累,系統對一些變量的變化區間是有容忍度的。一種是可以自我決策,降級是一種決策,一種是可以容忍變化。做到這樣系統已經非常智能了,雙 11 的時候不用做太多工作,大家可以看到曲線飆升,系統平穩運行,這是非常理想的。

同時隨着體量繼續增長,今天又迎來了一次技術升級的契機,所以希望在成本、體驗和吞吐能力上繼續探索,找到一個新的平衡點,能奉獻給大家更完美的雙 11。謝謝大家!

**Q1:**您上面提到的單元是怎麼劃分的?

** 丁宇:**剛纔講到買家業務和賣家業務,會把完整的買家業務部署在每一個單元,買家系統有多少我們很清楚。賣家系統不需要部署,因爲流量不會過來,只要梳理這些業務就可以了。但是阿里業務很複雜,林林總總,要看哪些系統屬於這個域,我們有個標識,配置驅動,標識是單元應用,就知道新建站點的時候某些應用要跟着單元走,同時部署還有個順序,跟着單元的建設一起走就可以。

**Q2:**一個完整的買家包括所有的服務做一個單元?

**丁宇:**對。

** Q3:**單元會有不同切換的情況在,那買家數據是怎麼保持同步的?

**丁宇:**單元化的方案對用戶流量來說比較簡單,我們數據層做了非常多的工作,實時的把買家在這個單元產生的數據同步到中心,賣家數據要同步到單元,都要實時做。比如說發現 1 秒的延時,要等數據同步完成才能切換過來,數據同步效率非常關鍵。

** Q4:**如果再極端一點,是某個壞掉的單元變成完全不可訪問的情況,這種產品怎麼切換?

** 丁宇:**這個數據是同步不出來的,這一塊要做一個權衡,就是流量必須切走,這會產生數據不一致,可以事後補償,要不然會產生更大的業務問題。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/ik2MOAEeg3bJsTgQnGITng