天天看點

架構設計之高可擴充性(上)

高可擴充性表示可通過加機器線性提高系統處理能力,承擔更高流量和并發。

由于峰值的流量不可控,不可能在系統架構設計初期就考慮好機器數量以支援并發。

一般基于成本考慮,在業務平穩期,會預留30%~50%備援機器應對營運活動或者推廣可能帶來的峰值流量,但當有突發事件時,流量可能瞬間提升幾倍。莫過于明星公布戀情,大家都會到兩人微網誌下互動,微網誌流量短時内迅速增長,微網誌資訊流也短暫出現無法重新整理消息,系統一時間不可用。

是以如何應對突發的流量呢?

最快的方式就是堆機器。不過能保證擴容三倍機器後,系統也能支撐三倍的流量嗎?

系統瓶頸在哪裡?

通過在單機系統中增加處理核心,可增加系統的并行處理能力,但當并行任務數較多時,系統會因為争搶資源而達到性能拐點,處理能力不升反降。

叢集系統也是這樣。不同的系統分層上可能存在一些“瓶頸”,這些瓶頸點制約着統的橫向擴充能力。

比如系統流量1000 QPS,對DB也是1000 QPS。若流量增加10倍,雖然系統可通過擴容正常服務,DB卻成瓶頸。或單機網絡帶寬50Mbps,若擴容到30台機器,前端負載均衡帶寬就超過千兆帶寬限制,也會成為瓶頸點。

是以系統中存在哪些服務會成為系統擴充的瓶頸呢?

無狀态的服務群組件很易于擴充,但是MySQL這種存儲服務有狀态,較難擴充。因為向存儲叢集中增減機器時,涉及大量資料遷移,一般關系型DB都不支援。

DB、緩存、依賴的第三方、負載均衡、交換機帶寬等都是系統擴充時需考慮因素。得清楚系統并發達到某量級後,哪個因素會成為系統瓶頸點,進而對症下藥。

高可擴充性設計

拆分,把龐雜系統拆分成獨立、單一職責的子產品。

注意對不同類型子產品,拆分原則不同。假如設計一個知乎,那麼會有幾個子產品呢?至少5個子產品。

使用者:負責維護社群使用者資訊,注冊,登陸等;

關系:使用者之間關注、好友、拉黑等關系的維護;

内容:社群發的内容,就像朋友圈或者微網誌的内容;

評論、贊:使用者可能會有的兩種正常互動操作;

搜尋:使用者的搜尋,内容的搜尋。

部署方式遵照最簡單三層部署架構

負載均衡負責請求的分發

應用伺服器負責業務邏輯的處理

資料庫負責資料的存儲落地

所有子產品的業務代碼混合,資料也都存在一個庫。

存儲層的擴充性

無論是存儲資料量,還是并發通路量,不同業務子產品間量級相差很大。

比如知乎,關系資料量遠大于使用者資料量,但使用者資料的通路量卻遠比關系資料大。是以假如存儲目前的瓶頸點是容量,那隻需針對關系子產品的資料做拆分,而無需拆分使用者子產品資料。是以存儲拆分首先考慮業務次元。

拆分後,這簡單社群系統就有使用者庫、内容庫、評論庫、點贊庫和關系庫。這還能隔離故障,某庫挂了不會影響到其它DB。

按DB業務拆分後的部署架構

架構設計之高可擴充性(上)

業務拆分一定程度提升了系統擴充性,但運作久後,單一業務DB在容量和并發請求量上仍會超過單機限制。需針對DB做二次拆分。

這次拆分按照資料特征做水準的拆分,比如給使用者庫增加倆節點,然後将使用者資料拆分庫。

水準拆分後,即可突破單機限制。不能随意地增加節點,因為一旦增加節點就需手動遷移資料。是以長遠考慮最好一次增加足夠節點,避免頻繁擴容。

當DB按業務和資料次元拆分後,盡量不要使用事務。因為當一個事務同時更新不同DB,需使用二階段送出,來協調所有DB要麼全部更新成功,要麼全部更新失敗。