在當今的互聯網業內,很多大型互聯網系統,比如淘寶、支付寶、網商銀行等,都已經實現了單元化架構,并從中獲益匪淺,更多企業正加入其中。為什么要做單元化,單元化架構能給系統帶來什么樣的能力。本文結合螞蟻集團支付寶系統的單元化架構建設實踐,闡釋單元化的原理與實現。
單點瓶頸
任何一個互聯網系統,不論是支付寶、淘寶,還是 Google、Facebook,當發展到一定規模時,都會不可避免地觸及到單點瓶頸。這里所說的“單點”,在系統的不同發展階段表現不同。
服務器和應用單點
在系統發展初期,服務器和應用單點最先成為瓶頸,解決的方法也很簡單,加機器、拆應用。
數據庫單點
緊接著數據庫單點,解決起來就開始不那么容易了,典型的做法是先垂直拆分,再水平拆分,在這個過程中需要解決多數據源、數據分片、透明訪問等問題。
機房單點
當應用越來越多、服務器越來越多、數據庫越來越多,單個機房的容量開始捉襟見肘,裝不下這么多服務器。而且業務量的增長也讓系統單機房運行的風險激增,一旦發生機房斷電或是其他災害導致機房故障,就會讓整個系統完全癱瘓。機房不能放在一個籃子里,必須讓系統在兩個或更多 IDC 內運行。
多機房部署通常有以下兩種模式:
垂直模式:將全站應用、數據庫等劃分為幾個部分,分別放在不同的機房中,完成一個業務可能需要不同機房中的不同應用提供服務。這就相當于在邏輯層面將一個物理機房放大了,機房容量不足的問題得以解決。
水平模式:每個機房中部署的應用都是相同的,每個機房都有完成全站所有業務的能力,在運行時每個機房都只承擔整站的一部分業務流量。
從具體實現角度來看,垂直模式更容易些,能夠突破機房容量瓶頸,但不具備容災能力。而容災,是一個發展到一定規模的互聯網系統的重要訴求,更是金融場景和金融業務必不可少的基礎能力,因此在具體實踐中,大多數大型系統都采用多機房水平擴展的模式。
單地部署
上面所說的容災問題,對于一個有著億級用戶的系統,或一個數據系統來說尤為重要,僅僅是機房級容災還不夠,必須要考慮部署地容災,也就是說不能把所有機房部署在地理上臨近的地區,以防發生地震、海嘯、核爆等劇烈災害而導致系統被毀滅性破壞。這類系統的典型代表是銀行、第三方支付等金融類系統,比如銀行就對機房部署有著經典的“兩地三中心”要求。于是,單地部署開始成為制約業務發展的瓶頸。
將系統的某個部分部署到距離較遠的另外一個地區(城市)的能力,是大型互聯網系統走向成熟的標志。多地部署本質上和多機房部署是一樣的,面臨的問題也幾乎一樣,除了距離問題。表象上是距離,下面隱藏著的是延時,更遠的距離意味著更長的延時,個位數毫秒的延時不會給系統帶來什么麻煩,但一旦這個數值變成幾十毫秒,量變就引發了質變,很多業務開始不能忍受和忽略延時帶來的影響。
單元化
多地多機房部署,是互聯網系統的必然發展方向,一個系統要走到這一步,也就必然要解決上面提到的問題:流量調配、數據拆分、延時等。業界有很多技術方案可以用來解決這些問題,而承載這些方案的,是一個部署架構。盡管可采用的部署架構不止一個,但不論是純理論研究,還是一些先行系統的架構實踐,都把“單元化部署”推崇為最佳方案。
單元(即單元化應用服務產品層的部署單元),是指一個能完成所有業務操作的自包含集合,在這個集合中包含了所有業務所需的所有服務,以及分配給這個單元的數據。單元化架構就是將單元作為部署的基本單位,在全站所有機房中部署多個單元,每個機房內單元數目不固定,任一單元均部署系統所需的全部應用,數據則是全量數據按照某種維度劃分后的一部分。
傳統意義上的 SOA 化(服務化)架構,服務是分層的,每層的節點數量不盡相同,上層調用下層時,隨機選擇節點。
單元化架構下,服務仍然是分層的,不同的是每一層中的任意一個節點都屬于且僅屬于某一個單元,上層調用下層時,僅會選擇本單元內的節點。
一個單元,是一個五臟俱全的縮小版整站,它是全能的,因為部署了所有應用;但它不是全量的,因為只能操作一部分數據。能夠單元化的系統,很容易在多機房中部署,因為可以輕松將多個單元部署在一個機房內,而將另外幾個單元部署在其他機房內。通過在業務入口處設置一個流量調配器,可以調整業務流量在單元之間的比例。
從上述對單元的定義和特性描述中,可以推導出單元化架構要求系統必須具備的一項能力:數據分區,實際上正是數據分區決定了各個單元可承擔的業務流量比例。數據分區(shard),即是將全局數據按照某一個維度水平劃分開來,每個分區的數據內容互不重疊,這也就是數據庫水平拆分所做的事情。
僅把數據分區了還不夠,單元化的另外一個必要條件是,全站所有業務數據分區所用的拆分維度和拆分規則都必須一樣。若是以用戶分區數據,那交易、收單、微貸、支付、賬務等全鏈路業務都應該基于用戶維度拆分數據,并且采用一樣的規則拆分出同樣的分區數。比如,以用戶 id 末 2 位作為標識,將每個業務的全量數據都劃分為 100 個分區(00-99)。
有了以上兩個基礎,單元化才可能成為現實。把一個或幾個數據分區,部署在某個單元內,這些數據分區占總量數據的比例,就是這個單元能夠承擔的業務流量比例。 執行數據分區時一個很重要的問題是分區維度的選擇,一個好的維度,應該:
粒度合適:粒度過大,會喪失流量調配的靈活性和精細度;粒度過小,會給數據的支撐資源,訪問邏輯帶來負擔。
足夠平均:按這個分區維度劃分后,每個部署單元的數據量應該是幾乎一致的。
以用戶為服務主體的系統(很多面向用戶的系統,比如支付寶)通常可以按用戶維度對數據分區,這是一個最佳實踐。
邏輯單元
邏輯單元是單元化架構的基礎,一個單元被稱為一個 Zone。根據業務特點不同,您可以將系統部署在不同類型的邏輯單元中。更多信息,請參考 創建邏輯單元。