大型分散式網站架構實戰專案分析

爛豬皮發表於2018-04-26

一、分散式系統是什麼?

1、定義

distributed system is one in which components located at networked computers communicate and coordinate their actions only by passing messages(分散式系統是指位於網路計算機的元件僅通過傳遞訊息來通訊和協調其行為的系統。)

所以,從這可以總結出這幾個重點:

1、元件是分佈在網路計算機上
2、元件之間僅僅通過訊息傳遞來通訊並且協調工作

clipboard.png

2、特性

2.1、副本
(Replica)是分散式系統最常見的概念之一,指分散式系統對資料和服務提供的一種冗餘方式。在常見的分散式系統中,為了對外提供高可用的服務,我們往往會對資料和服務進行副本處理。

1)資料副本指在不同節點上持久同一份資料,當某一個節點上儲存的資料丟失時,可以從副本上讀取到該資料,這是解決分散式系統資料丟失問題的有效手段。

2)服務副本指多個節點提供同樣的服務,每個節點都有能力接受來自外部的請求並進行相應的處理。

2.2、併發性

在程式執行過程中的併發性操作是非常常見的行為,例如同一個分散式系統中的多個節點,可能會併發地操作一些共享的資源,如何準確並高效的協調分散式併發操作也成為了分散式系統架構與設計中最大的挑戰之一。

2.3、全域性時鐘

分散式系統是有一系列在空間上隨意分佈的多個程式組成的,在這些程式之間通過交換訊息來進行相互通訊。因此,在分散式系統中,很難定義兩個事件究竟誰先誰後,原因就是分散式系統缺乏一個全域性的時鐘序列控制。

2.4、故障總會發生

任何在設計階段考慮到的異常情況,一定會在系統實際執行中發生,並且,在系統實際執行過程中還會遇到很多在設計時未能考慮到的異常故障。所以,除非需求指標允許,在系統設計時不能放過任何異常情況。

3、分散式環境的各種問題

3.1、通訊異常

網路本身的不可靠性,各節點之間的網路通訊能夠正常進行,其延時也會遠大於單機操作。單機記憶體訪問的延時在納秒數量級(通常是10ns左右),而正常的一次網路通訊的延遲在0.1~1ms左右,巨大的延時差別,會影響訊息的收發的過程,因此訊息丟失和訊息延遲變得非常普遍。

3.2、網路分割槽

當網路由於發生異常情況,導致分散式系統中部分節點之間的網路延時不斷增大,最終導致組成分散式系統的左右節點中,只有部分節點能夠進行正常通訊,而另一些節點則不能,這個現象成為網路分割槽,俗稱“鬧裂”。當網路分割槽出現時,分散式系統就出現區域性小叢集,在極端情況下,這些小叢集會獨立完成原本需要整個分散式系統才能完成的功能,包括對資料的事務處理,這對分散式一致性提出了非常大的挑戰。

3.3、三態

在分散式環境下,網路可能出現各式各樣的問題,因此分散式系統的每一次請求與響應,存在特有的三態概念,即成功、失敗與超時。超時現象通常有一下兩種情況:

1)由於網路原因,該請求(訊息)並沒有被成功傳送到接收方,而是在傳送過程就發生了訊息丟失現象。

2)該請求(訊息)成功的被接收方接受後,並進行了處理,但是在將響應反饋給傳送方的過程中,發生了訊息丟失現象。

當出現這樣的超時現象時,網路通訊的發起方是無法確定當前請求是否被成功處理的。

3.4、節點故障

分散式系統下比較常見的問題,指組成分散式系統的伺服器節點出現當機或僵死現象。

二、怎麼去定義大型網站

滿足一個大型網站的基本因素:

  • 訪問量

  • 業務複雜度

  • 資料量

三、大型網站常用到的技術框架

初始階段的網站架構

一般來講,大型網站都是從小型網站發展而來,一開始的架構都比較簡單,隨著業務複雜和使用者量的激增,才開始做很多架構上的改進。當它還是小型網站的時候,沒有太多訪客,一般來講只需要一臺伺服器就夠了,這時應用程式、資料庫、檔案等所有資源都在一臺伺服器上,網站架構如下圖所示:

clipboard.png

應用服務和資料服務分離

隨著網站業務的發展和使用者量的增加,一臺伺服器就無法再滿足需求了。大量使用者訪問導致訪問速度越來越慢,而逐漸增加的資料也會導致儲存空間不足。這時就需要將應用和資料分離,應用和資料分離後整個網站使用 3 臺伺服器:應用伺服器、檔案伺服器和資料庫伺服器。這 3 臺伺服器對硬體資源的要求各不相同:

  • 應用伺服器業務邏輯,需要強大的CPU

  • 資料庫伺服器對磁碟讀寫操作很多,需要更快的磁碟和更大的記憶體

  • 檔案伺服器儲存使用者上傳的檔案,因此需要更大的磁碟空間

此時,網站系統的架構如下圖所示:

clipboard.png

使用快取改善網站效能

隨著使用者再增加,網站又會一次面臨挑戰:資料庫壓力太大導致整站訪問效率再此下降,使用者體驗受到影響。一個網站,往往 80% 的業務訪問集中在 20% 的資料上,比如微博請求量最多的肯定是那些千萬級粉絲的大 V 的微博,而幾乎沒有人關注的你的首頁,除了自己想起來之外根本不會被開啟。既然大部分業務訪問集中在一小部分資料上,那就把這一小部分資料先提前快取在記憶體中,而不是每次都去資料庫讀取,這樣就可以減少資料庫的訪問壓力,從而提高整個網站的訪問速度。

網站使用的快取一般分為快取到應用伺服器或者快取在專門的分散式快取伺服器。快取到應用伺服器自己的訪問速度快很多,但是受自身記憶體限制,往往不太適用。遠端分散式快取使用一個叢集專門負責快取服務,當記憶體不夠還可以輕鬆得動態擴容。

clipboard.png

使用應用伺服器叢集改善網站的併發處理能力

使用快取後,資料訪問壓力得到了緩解,但是單一應用伺服器能夠處理的請求連線有限,在網站訪問高峰期,應用伺服器就成了整個網站的效率瓶頸。使用分散式叢集是網站解決高併發、海量資料問題的常用手段。當一臺伺服器的處理能力和儲存空間不足時,不要嘗試去更換更強大的伺服器,對大型網站而言,多麼強大的伺服器,都滿足不了網站持續增長的業務需求。這種情況下,更恰當的做法是增加一臺伺服器分擔原有伺服器的訪問及儲存壓力。 對網站架構而言,只要能通過增加一臺伺服器的方式改善負載壓力,就可以以同樣的方式持續增加伺服器不斷改善系統效能,從而實現系統的可伸縮性。應用伺服器實現叢集是網站可伸縮架構設計中較為簡單成熟的一種,如下圖所示:

clipboard.png通過負載均衡排程伺服器,可以將來自使用者瀏覽器的訪問請求分發到應用伺服器叢集中的任何一臺伺服器上,如果有更多使用者,就在叢集中加入更多的應用伺服器,使應用伺服器的壓力不再成為整個網站的瓶頸。

資料庫讀寫分離

網站在使用快取後,使對大部分資料讀操作訪問都可以不通過資料庫就能完成,但是仍有一部分讀操作(快取訪問不命中、快取過期)和全部的寫操作都需要訪問資料庫,在網站的使用者達到一定規模後,資料庫因為負載壓力過高而成為網站的瓶頸。 目前大部分的主流資料庫都提供主從熱備功能,通過配置兩臺資料庫主從關係,可以將一臺資料庫伺服器的資料更新同步到另一臺伺服器上。網站利用資料庫的這一功能,實現資料庫讀寫分離,從而改善資料庫負載壓力。如下圖所示:

clipboard.png應用伺服器在寫資料的時候,訪問主資料庫,主資料庫通過主從複製機制將資料更新同步到從資料庫,這樣當應用伺服器讀資料的時候,就可以通過從資料庫獲得資料。為了便於應用程式訪問讀寫分離後的資料庫,通常在應用伺服器端使用專門的資料訪問模組,使資料庫讀寫分離對應用透明。

使用反向代理和 CDN 加速網站響應

隨著網站業務不斷髮展,使用者規模越來越大,由於中國複雜的網路環境,不同地區的使用者訪問網站時,速度差別也極大。有研究表明,網站訪問延遲和使用者流失率正相關,網站訪問越慢,使用者越容易失去耐心而離開。為了提供更好的使用者體驗,留住使用者,網站需要加速網站訪問速度。主要手段有使用 CDN 和反向代理。如下圖所示:

clipboard.png

使用分散式檔案系統和分散式資料庫系統

任何強大的單一伺服器都滿足不了大型網站持續增長的業務需求。資料庫經過讀寫分離後,從一臺伺服器拆分成兩臺伺服器,但是隨著網站業務的發展依然不能滿足需求,這時需要使用分散式資料庫。檔案系統也一樣,需要使用分散式檔案系統。如下圖所示:

clipboard.png

分散式資料庫是網站資料庫拆分的最後手段,只有在單表資料規模非常龐大的時候才使用。不到不得已時,網站更常用的資料庫拆分手段是業務分庫,將不同業務的資料部署在不同的物理伺服器上。

使用 NoSQL 和搜尋引擎

隨著網站業務越來越複雜,對資料儲存和檢索的需求也越來越複雜,網站需要採用一些非關聯式資料庫技術如 NoSQL 和非資料庫查詢技術如搜尋引擎。如下圖所示:

clipboard.png

NoSQL 和搜尋引擎都是源自網際網路的技術手段,對可伸縮的分散式特性具有更好的支援。應用伺服器則通過一個統一資料訪問模組訪問各種資料,減輕應用程式管理諸多資料來源的麻煩。

業務拆分

大型網站為了應對日益複雜的業務場景,通過使用分而治之的手段將整個網站業務分成不同的產品線。如大型購物交易網站都會將首頁、商鋪、訂單、買家、賣家等拆分成不同的產品線,分歸不同的業務團隊負責。

具體到技術上,也會根據產品線劃分,將一個網站拆分成許多不同的應用,每個應用獨立部署。應用之間可以通過一個超連結建立關係(在首頁上的導航連結每個都指向不同的應用地址),也可以通過訊息佇列進行資料分發,當然最多的還是通過訪問同一個資料儲存系統來構成一個關聯的完整系統,如下圖所示:

clipboard.png

分散式服務

隨著業務拆分越來越小,儲存系統越來越龐大,應用系統的整體複雜度呈指數級增加,部署維護越來越困難。由於所有應用要和所有資料庫系統連線,在數萬臺伺服器規模的網站中,這些連線的數目是伺服器規模的平方,導致資料庫連線資源不足,拒絕服務。

既然每一個應用系統都需要執行許多相同的業務操作,比如使用者管理、商品管理等,那麼可以將這些共用的業務提取出來,獨立部署。由這些可複用的業務連線資料庫,提供共用業務服務,而應用系統只需要管理使用者介面,通過分散式服務呼叫共用業務服務完成具體業務操作。如下圖所示:

clipboard.png

在此我向大家推薦一個架構學習交流群。交流學習群號:575745314 裡面會分享一些資深架構師錄製的視訊錄影:有Spring,MyBatis,Netty原始碼分析,高併發、高效能、分散式、微服務架構的原理,JVM效能優化、分散式架構等這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多

大型分散式網站架構實戰專案分析

四、電商網站架構案例

1、電商案例的原因

分散式大型網站,目前看主要有幾類1.大型門戶,比如網易,新浪等;2.SNS網站,比如校內,開心網等;3.電商網站:比如阿里巴巴,京東商城,國美線上,汽車之家等。大型門戶一般是新聞類資訊,可以使用CDN,靜態化等方式優化,開心網等互動性比較多,可能會引入更多的NOSQL,分散式快取,使用高效能的通訊框架等。電商網站具備以上兩類的特點,比如產品詳情可以採用CDN,靜態化,互動性高的需要採用NOSQL等技術。因此,我們採用電商網站作為案例,進行分析。

2、電商網站需求

客戶需求:

  • 建立一個全品類的電子商務網站(B2C),使用者可以線上購買商品,可以線上支付,也可以貨到付款;

  • 使用者購買時可以線上與客服溝通;

  • 使用者收到商品後,可以給商品打分,評價;

  • 目前有成熟的進銷存系統;需要與網站對接;

  • 希望能夠支援3~5年,業務的發展;

  • 預計3~5年使用者數達到1000萬;

  • 定期舉辦雙11,雙12,三八男人節等活動;

  • 其他的功能參考京東或國美線上等網站。

客戶就是客戶,不會告訴你具體要什麼,只會告訴你他想要什麼,我們很多時候要引導,挖掘客戶的需求。好在提供了明確的參考網站。因此,下一步要進行大量的分析,結合行業,以及參考網站,給客戶提供方案。

其他的略

~

需求功能矩陣

需求管理傳統的做法,會使用用例圖或模組圖(需求列表)進行需求的描述。這樣做常常忽視掉一個很重要的需求(非功能需求),因此推薦大家使用需求功能矩陣,進行需求描述。

本電商網站的需求矩陣如下:

clipboard.png以上是對電商網站需求的簡單舉例,目的是說明(1)需求分析的時候,要全面,大型分散式系統重點考慮非功能需求;(2)描述一個簡單的電商需求場景,使大家對下一步的分析設計有個依據。

3、網站初級架構

一般網站,剛開始的做法,是三臺伺服器,一臺部署應用,一臺部署資料庫,一臺部署NFS檔案系統。

這是前幾年比較傳統的做法,之前見到一個網站10萬多會員,垂直服裝設計門戶,N多圖片。使用了一臺伺服器部署了應用,資料庫以及圖片儲存。出現了很多效能問題。

如下圖:

clipboard.png

但是,目前主流的網站架構已經發生了翻天覆地的變化。一般都會採用叢集的方式,進行高可用設計。至少是下面這個樣子。

clipboard.png

使用叢集對應用伺服器進行冗餘,實現高可用;(負載均衡裝置可與應用一塊部署)使用資料庫主備模式,實現資料備份和高可用;

4、系統容量預估

預估步驟:

(1) 註冊使用者數-日均UV量-每日的PV量-每天的併發量;

(2) 峰值預估:平常量的2~3倍;

(3) 根據併發量(併發,事務數),儲存容量計算系統容量。

(4 ) 客戶需求:3~5年使用者數達到1000萬註冊使用者;

每秒併發數預估:

(1) 每天的UV為200萬(二八原則);

(2) 每日每天點選瀏覽30次;

(3) PV量:200*30=6000萬;

(4) 集中訪問量:24

0.2=4.8小時會有6000萬
0.8=4800萬(二八原則);

(5) 每分併發量:4.8*60=288分鐘,每分鐘訪問4800/288=16.7萬(約等於);

(6) 每秒併發量:16.7萬/60=2780(約等於);

(7) 假設:高峰期為平常值的三倍,則每秒的併發數可以達到8340次。

(8) 1毫秒=1.3次訪問;

伺服器預估:(以tomcat伺服器舉例)

(1) 按一臺web伺服器,支援每秒300個併發計算。平常需要10臺伺服器(約等於);[tomcat預設配置是150]

(2) 高峰期:需要30臺伺服器;

容量預估:70/90原則

系統CPU一般維持在70%左右的水平,高峰期達到90%的水平,是不浪費資源,並比較穩定的。記憶體,IO類似。

以上預估僅供參考,因為伺服器配置,業務邏輯複雜度等都有影響。在此CPU,硬碟,網路等不再進行評估。

電網網站架構案例系列的第二篇文章。主要講解網站架構分析,網站架構優化,業務拆分,應用叢集架構,多級快取,分散式Session。

5、網站架構分析

根據以上預估,有幾個問題:

  • 需要部署大量的伺服器,高峰期計算,可能要部署30臺Web伺服器。並且這三十臺伺服器,只有秒殺,活動時才會用到,存在大量的浪費。

  • 所有的應用部署在同一臺伺服器,應用之間耦合嚴重。需要進行垂直切分和水平切分。

  • 大量應用存在冗餘程式碼

  • 伺服器SESSION同步耗費大量記憶體和網路頻寬

  • 資料需要頻繁訪問資料庫,資料庫訪問壓力巨大。

大型網站一般需要做以下架構優化(優化是架構設計時,就要考慮的,一般從架構/程式碼級別解決,調優主要是簡單引數的調整,比如JVM調優;如果調優涉及大量程式碼改造,就不是調優了,屬於重構):

  • 業務拆分

  • 應用叢集部署(分散式部署,叢集部署和負載均衡)

  • 多級快取

  • 單點登入(分散式Session)

  • 資料庫叢集(讀寫分離,分庫分表)

  • 服務化

  • 訊息佇列

  • 其他技術

五、網站架構優化

1、業務拆分

根據業務屬性進行垂直切分,劃分為產品子系統,購物子系統,支付子系統,評論子系統,客服子系統,介面子系統(對接如進銷存,簡訊等外部系統)。

根據業務子系統進行等級定義,可分為核心系統和非核心繫統。核心系統:產品子系統,購物子系統,支付子系統;非核心:評論子系統,客服子系統,介面子系統。

業務拆分作用:提升為子系統可由專門的團隊和部門負責,專業的人做專業的事,解決模組之間耦合以及擴充套件性問題;每個子系統單獨部署,避免集中部署導致一個應用掛了,全部應用不可用的問題。

等級定義作用:用於流量突發時,對關鍵應用進行保護,實現優雅降級;保護關鍵應用不受到影響。

拆分後的架構圖:

clipboard.png

參考部署方案2

2、應用叢集部署(分散式,叢集,負載均衡)

  • 分散式部署:將業務拆分後的應用單獨部署,應用直接通過RPC進行遠端通訊;

  • 叢集部署:電商網站的高可用要求,每個應用至少部署兩臺伺服器進行叢集部署;

  • 負載均衡:是高可用系統必須的,一般應用通過負載均衡實現高可用,分散式服務通過內建的負載均衡實現高可用,關係型資料庫通過主備方式實現高可用。

叢集部署後架構圖:

clipboard.png

3、 多級快取

快取按照存放的位置一般可分為兩類本地快取和分散式快取。本案例採用二級快取的方式,進行快取的設計。一級快取為本地快取,二級快取為分散式快取。(還有頁面快取,片段快取等,那是更細粒度的劃分)

一級快取,快取資料字典,和常用熱點資料等基本不可變/有規則變化的資訊,二級快取快取需要的所有快取。當一級快取過期或不可用時,訪問二級快取的資料。如果二級快取也沒有,則訪問資料庫。

快取的比例,一般1:4,即可考慮使用快取。(理論上是1:2即可)。

clipboard.png

根據業務特性可使用以下快取過期策略:

(1) 快取自動過期;

(2) 快取觸發過期;

4、單點登入(分散式Session)

系統分割為多個子系統,獨立部署後,不可避免的會遇到會話管理的問題。一般可採用Session同步,Cookies,分散式Session方式。電商網站一般採用分散式Session實現。

再進一步可以根據分散式Session,建立完善的單點登入或賬戶管理系統。

clipboard.png

流程說明

1) 使用者第一次登入時,將會話資訊(使用者Id和使用者資訊),比如以使用者Id為Key,寫入分散式Session;

(2) 使用者再次登入時,獲取分散式Session,是否有會話資訊,如果沒有則調到登入頁;

(3) 一般採用Cache中介軟體實現,建議使用Redis,因此它有持久化功能,方便分散式Session當機後,可以從持久化儲存中載入會話資訊;

(4) 存入會話時,可以設定會話保持的時間,比如15分鐘,超過後自動超時;

結合Cache中介軟體,實現的分散式Session,可以很好的模擬Session會話。

5、資料庫叢集(讀寫分離,分庫分表)

大型網站需要儲存海量的資料,為達到海量資料儲存,高可用,高效能一般採用冗餘的方式進行系統設計。一般有兩種方式讀寫分離和分庫分表。

讀寫分離:一般解決讀比例遠大於寫比例的場景,可採用一主一備,一主多備或多主多備方式。

本案例在業務拆分的基礎上,結合分庫分表和讀寫分離。如下圖:

clipboard.png

(1) 業務拆分後:每個子系統需要單獨的庫;

(2) 如果單獨的庫太大,可以根據業務特性,進行再次分庫,比如商品分類庫,產品庫;

(3) 分庫後,如果表中有資料量很大的,則進行分表,一般可以按照Id,時間等進行分表;(高階的用法是一致性Hash)

(4) 在分庫,分表的基礎上,進行讀寫分離;

相關中介軟體可參考Cobar(阿里,目前已不在維護),TDDL(阿里),Atlas(奇虎360),MyCat(在Cobar基礎上,國內很多牛人,號稱國內第一開源專案)。

分庫分表後序列的問題,JOIN,事務的問題,會在分庫分表主題分享中,介紹。

6、服務化

將多個子系統公用的功能/模組,進行抽取,作為公用服務使用。比如本案例的會員子系統就可以抽取為公用的服務。

clipboard.png

7、訊息佇列

訊息佇列可以解決子系統/模組之間的耦合,實現非同步,高可用,高效能的系統。是分散式系統的標準配置。本案例中,訊息佇列主要應用在購物,配送環節。

(1) 使用者下單後,寫入訊息佇列,後直接返回客戶端;

(2) 庫存子系統:讀取訊息佇列資訊,完成減庫存;

(3) 配送子系統:讀取訊息佇列資訊,進行配送;

目前使用較多的MQ有Active MQ,Rabbit MQ,Zero MQ,MS MQ等,需要根據具體的業務場景進行選擇。建議可以研究下Rabbit MQ。

8、其他架構(技術)

除了以上介紹的業務拆分,應用叢集,多級快取,單點登入,資料庫叢集,服務化,訊息佇列外。還有CDN,反向代理,分散式檔案系統,大資料處理等系統。

此處不詳細介紹,大家可以問度娘/Google,有機會的話也可以分享給大家。

在此我向大家推薦一個架構學習交流群。交流學習群號:575745314 裡面會分享一些資深架構師錄製的視訊錄影:有Spring,MyBatis,Netty原始碼分析,高併發、高效能、分散式、微服務架構的原理,JVM效能優化、分散式架構等這些成為架構師必備的知識體系。還能領取免費的學習資源,目前受益良多

六、架構總結

clipboard.png

以上是本次分享的架構總結,其中細節可參考前面分享的內容。其中還有很多可以優化和細化的地方,因為是案例分享,主要針對重要部分做了介紹,工作中需要大家根據具體的業務場景進行架構設計。


相關文章