1. 程式人生 > >《大型網站技術架構》讀書筆記之六:永無止境之網站的伸縮性架構

《大型網站技術架構》讀書筆記之六:永無止境之網站的伸縮性架構

映射 應對 方法 訂閱 知識 位置 n+1 轉換 bsp

此篇已收錄至《大型網站技術架構》讀書筆記系列目錄貼,點擊訪問該目錄可獲取更多內容。

首先,所謂網站的伸縮性,指不需要改變網站的軟硬件設計,僅僅通過改變部署的服務器數量就可以擴大或者縮小網站的服務處理能力。在整個互聯網行業的發展漸進演化中,最重要的技術就是服務器集群,通過不斷地向集群中添加服務器來增強整個集群的處理能力。

一、網站架構的伸縮性設計

1.1 不同功能進行物理分離實現伸縮

  (1)縱向分離:將業務處理流程上得不同部分分離部署,實現系統的伸縮性;

技術分享

  (2)橫向分離:將不同的業務模塊分離部署,實現系統的伸縮性;

技術分享

1.2 單一功通過集群規模實現伸縮

  使用服務器集群,即將相同服務部署在多臺服務器上構成一個集群整體對外提供服務。具體來說,集群伸縮性又分為應用服務器集群伸縮性和數據服務器集群伸縮性。這兩種集群對於數據狀態管理的不同,技術實現也有很大的區別。

 It is said that 當一頭牛拉不動車的時候,不要去尋找一頭更強壯的牛,而是用兩頭牛來拉車

技術分享

二、應用服務器集群的伸縮性設計

2.1 應用服務器那點必須知道的事兒

  (1)應用服務器應該被設計成無狀態的,即應用服務器不存儲請求上下文信息;構建集群後,每次用戶的請求都可以發到集群中任意一臺服務器上處理,任何一臺服務器的處理結果都是相同的;

  (2)HTTP本身是一個無狀態的連接協議,為了支持客戶端與服務器之間的交互,我們就需要通過不同的技術為交互存儲狀態,而這些不同的技術就是Cookie和Session了。

  (3)HTTP請求的分發是應用服務器集群實現伸縮性的核心問題,而負載均衡服務器就是HTTP請求的分發裝置,它是網站必不可少的基礎手段,也被稱為網站的殺手鐧

之一。

2.2 負載均衡技術—網站必不可少的基礎技術手段

  負載均衡的實現方式多種多樣,從硬件到軟件,從商業產品到開源產品,應有盡有。但是,實現負載均衡的基礎技術不外乎以下幾種:

  (1)HTTP重定向負載均衡  評價:★★

技術分享

  此方案的優點是簡單易行,缺點是:

  ①瀏覽器需要兩次請求才能完成一次訪問,性能較差

  ②重定向服務器自身的處理能力有可能成為瓶頸,整個集群的伸縮性規模有限

  ③使用HTTP 302重定向有可能使搜索引擎判斷為SEO作弊,降低搜索排名;

  (2)DNS域名解析負載均衡  評價:★★★

技術分享

  此方案要求在DNS服務器中配置多個A記錄,例如:

www.mysite.com IN A 114.100.80.1
www.mysite.com IN A 114.100.80.2
www.mysite.com IN A 114.100.80.3

  此方案的優點是將負載均衡的工作轉交給了DNS,省掉了網站管理維護負載均衡服務器的麻煩。而缺點是:

  ①目前的DNS是多級解析,每一級DNS都可能緩存A記錄,當某臺服務器下線後,即使修改了DNS的A記錄,要使其生效仍然需要較長時間。這段期間,會導致用戶訪問已經下線的服務器造成訪問失敗。

  ②DNS負載均衡的控制權在域名服務商那裏,網站無法對其做更多改善和管理;

TIPS:事實上,大型網站總是部分使用DNS域名解析,利用域名解析作為第一級負載均很手段,即域名解析得到的一組服務器不是實際的Web服務器,而是同樣提供負載均衡的內部服務器,這組內部服務器再進行負載均衡,請求分發到真實的Web服務器上。

  (3)反向代理負載均衡  評價:★★★★

技術分享

  Web服務器不需要使用外部IP地址,而反向代理服務器則需要配置雙網卡和內外部兩套IP地址。

  此方案的優點是和反向代理服務器功能集成在一起,部署簡單。缺點是反向代理服務器是所有請求和響應的中轉站,其性能可能會成為瓶頸

  (4)IP負載均衡  評價:★★★★

技術分享

  此方案優點在於在內核進程完成數據分發,較反向代理負載均衡(在應用程序中分發數據)有更好的處理性能。缺點是由於所有請求響應都需要經過負載均衡服務器,集群的最大響應數據吞吐量不得不受制於負載均衡服務器網卡帶寬

  (5)數據鏈路層負載均衡  評價:★★★★★

技術分享

  此種方式又稱作三角傳輸模式,負載均衡數據分發過程中不修改IP地址,只修改mac地址,由於實際處理請求的真實物理IP地址和數據請求目的IP地址一致,所以不需要通過負載均衡服務器進行地址轉換,可將響應數據包直接返回給用戶瀏覽器,避免負載均衡服務器網卡帶寬成為瓶頸。這種負載均衡方式又稱作直接路由方式(DR)

  使用三角傳輸模式的鏈路層負載均衡是目前大型網站使用最廣泛的一種負載均衡手段。在Linux平臺上最好的鏈路層負載均衡開源產品是LVS(Linux Virutal Server)。

2.3 負載均衡算法—負載均衡技術賴以生存的核心

  前面的方法解決了負載均衡通過何種方式實現,而更為重要的則是如何從Web服務器列表中計算得到一臺Web服務器的地址,而這正是負載均衡的核心—算法。這裏簡單介紹一下通常的集中負載均衡計算的算法,如果需要深入了解請自行百度。

  (1)輪詢

  所有請求被以此分發到每臺應用服務器上,即每臺服務器需要處理的請求數目都相同,適合於所有服務器硬件都相同的場景。

  (2)加權輪詢

  根據應用服務器的配置性能的情況,在輪詢的基礎上,按照配置的權重將請求分發到每個服務器,高性能的服務器能分配更多的請求。

  (3)隨機

  此算法比較簡單實用,請求被隨機分配到各個應用服務器,因為好的隨機數本身就很均衡。

  (4)最少連接

  記錄每個應用服務器正在處理的連接數(請求數),將新到的請求分發到最少連接的服務器上,應該說,這是最符合負載均衡定義的算法。

  (5)源地址散列

  根據請求來源的IP地址進行Hash計算得到應用服務器,這樣來自同一個IP地址的請求總在同一個服務器上處理,該請求的上下文信息可以存儲在這臺服務器上,在一個會話周期內重復使用,從而實現會話粘滯。

三、分布式緩存集群的伸縮性設計

  不同於應用服務器集群的伸縮性設計,分布式緩存集群的伸縮性不能使用簡單的負載均衡手段來實現。因為:分布式緩存服務器集群中緩存的數據各不相同,緩存訪問請求不可以在緩存服務器集群中的任意一臺處理,必須先找到緩存有需要的數據的服務器,然後才能訪問

  分布式緩存集群伸縮性設計的目標:讓新上線的緩存服務器對整個分布式緩存集群影響最小,也就是說新加入緩存服務器後應使整個緩存服務器集群中已經緩存的數據盡可能還被訪問到。

  (1)以Memcached為代表的分布式緩存集群的訪問模型

技術分享

  以上圖片展示了一個典型的緩存寫操作,應用程序需要寫緩存數據<‘CHENGDU‘,DATA>,API將KEY(‘CHENGDU‘)輸入路由算法模塊,路由算法根據KEY和Memcached服務器集群列表計算得到一臺服務器編號(如Node1),進而得到該機器的IP地址和端口(10.0.0.1:91000)。然後,API調用通信模塊和編號為Node1的Memcached服務器進行通信,將數據<‘CHENGDU‘,DATA>寫入該服務器,至此便完成了一次分布式緩存的寫操作。

  而讀操作和寫操作一樣,使用同樣的路由算法和服務器列表,只要提供相同的KEY(如上面提到的‘CHENGDU‘),Memcached客戶端總是訪問相通的服務器(如上面計算得到的Node1)去讀取數據。

  (2)以Memcached為代表的分布式緩存集群的伸縮性挑戰

  簡單的路由算法(通過使用余數Hash)無法滿足業務發展時服務器擴容的需要:緩存命中率下降。例如:當3臺服務器擴容至4臺時,采用普通的余數Hash算法會導致大約75%(3/4)被緩存了的數據無法正確命中,隨著服務器集群規模的增大,這個比例會線性地上升。那麽,可以想象,當100臺服務器的急群眾加入一臺服務器,不能命中的概率大概是99%(N/N+1),這個結果顯然是無法接受的。

  那麽,能否通過改進路由算法,使得新加入的服務器不影響大部分緩存數據的正確性呢?請看下面的一致性Hash算法。

  (3)分布式緩存的一致性Hash算法

說明:一致性Hash算法是分布式緩存的核心理論,這裏只是簡單介紹一下,後續有空我會單獨寫一篇文章來詳細介紹一致性Hash算法,以及用C#實現一致性Hash算法。

  一致性Hash算法通過一個叫做一致性Hash還的數據結構實現KEY到緩存服務器的Hash映射,如下圖所示:

技術分享

  具體算法過程是:

  ①先構造一個長度為0~2^32(2的32次冪)個的整數環(又稱:一致性Hash環),根據節點名稱的Hash值將緩存服務器節點防置在這個Hash環中,如上圖中的node1,node2等;

  ②根據需要緩存的數據的KEY值計算得到其Hash值,如上圖中右半部分的“鍵”,計算其Hash值後離node2很近;

  ③在Hash環上順時針查找距離這個KEY的Hash值最近的緩存服務器節點,完成KEY到服務器的Hash映射查找,如上圖中離右邊這個鍵的Hash值最近的順時針方向的服務器節點是node2,因此這個KEY會到node2中讀取數據;

  當緩存服務器集群需要擴容的時候,只需要將新加入的節點名稱(如node5)的Hash值放入一致性Hash環中,由於KEY總是順時針查找距離其最近的節點,因此新加入的節點只影響整個環中的一部分。如下圖中所示,添加node5後,只影響右邊逆時針方向的三個Key/Value對數據,只占整個Hash環中的一小部分。

技術分享

  因此,我們可以與之前的普通余數Hash作對比:采用一直性Hash算法時,當3臺服務器擴容到4臺時,可以繼續命中原有緩存數據的概率為75%,遠高於普通余數Hash的25%,而且隨著集群規模越大,繼續命中原有緩存數據的概率也會隨之增大。當100臺服務器增加1臺時,繼續命中的概率是99%。雖然,仍有小部分數據緩存在服務器中無法被讀取到,但是這個比例足夠小,通過訪問數據庫也不會對數據庫造成致命的負載壓力

四、數據存儲服務器集群的伸縮性設計

  首先,數據存儲服務器必須保證數據的可靠存儲,任何情況下都必須保證數據的可用性和正確性。因此,緩存服務器集群的伸縮性架構方案不能直接適用於數據庫等存儲服務器。

  (1)關系數據庫集群的伸縮性設計

  ①市場上主要的關系數據庫都支持數據復制功能,使用這個功能可以對數據庫進行簡單伸縮。下圖顯示了使用數據復制的MySQL集群伸縮性方案:多臺MySQL的角色有主從之分,寫操作都在主服務器上,由主服務器將數據同步到集群中其他從服務器。而讀操作及數據分析等離線操作都會在從服務器上完成。

技術分享

  ②前面提到的業務分割模式也可以用在數據庫,不同業務數據表部署在不同的數據庫集群上,這就是所謂的“數據分庫”;但是其有一個制約條件:跨庫的表無法進行Join操作;

技術分享

  ③在實際運維中,對一些單表數據仍然很大的表,例如Facebook的用戶數據庫、淘寶的商品數據庫等,還需要進行分片,將一張表拆分開分別存儲在多個數據庫中,這就是所謂的“數據分片”;

技術分享

  (2)NoSQL數據庫的伸縮性設計

  首先,NoSQL主要指非關系的、分布式的數據庫設計模式。也有許多專家將NoSQL解讀為Not Only SQL,表示NoSQL是關系數據庫的補充,而不是替代方案。一般而言,NoSQL數據庫產品都放棄了關系數據庫的兩大重要基礎:①以關系代數為基礎的結構化查詢語言(SQL)②事務的一致性保證(ACID);與之對應的是強化一些大型網站更關註的特性:高可用性和可伸縮性

  開源社區的NoSQL產品不盡其數,其支持的數據結構和伸縮性特性也各不相同。目前看來,應用最廣泛的是Apache HBase。HBase的伸縮性主要依賴於其可分裂的HRegion可伸縮的分布式文件系統HDFS(如果您不知道HDFS又對HDFS有興趣,可以閱讀我的另一篇博文《不怕故障的海量存儲—HDFS基礎入門》)實現。

技術分享

  上圖是HBase的整體架構圖:

  ①HBase中數據以HRegion為單位進行管理,也就是說應用程序如果想要訪問一個數據,必須先找到HRegion,然後將數據讀寫操作提交給HRegion,由HRegion完成存儲層面的數據操作。

  ②每個HRegion中存儲一段Key區間(例如:[Key1,Key2))的數據,HRegionServer是物理服務器,每個HRegionServer上可以啟動多個HRegion實例。當一個HRegion中寫入的數據太多,達到配置的閥值時,HRegion會分裂成兩個HRegion,並將HRegion在整個集群中進行遷移,以使HRegionServer的負載均衡。

  ③所有的HRegion的信息都(例如:存儲的Key值區間、所在HRegionServer的IP地址和端口號等)記錄在HMaster服務器上。同時為了保證高可用,HBase啟動了多個HMaster,並通過ZooKeeper(一個支持分布式一致性的數據管理服務)選舉出一個主服務器,通過這個主HMaster服務器獲得Key值所在的HRegionServer,最後請求該HRegionServer上的HRegion實例,獲得需要的數據。其具體的數據尋址訪問流程如下圖所示:

技術分享

五、學習小結

  在本章的學習中,我們了解到要實現網站的可伸縮性,關鍵技術就在於如何構建“良好”的服務器集群。要達到良好的目標,就要求每次擴容和減少服務器時,對整個網站的影響是最小的,甚至無影響的。伸縮性是復雜的,沒有通用的、完美的解決方案和產品。一個具有良好伸縮性的網站,其設計總是走在業務發展的前面,在業務需要處理更多訪問和處理之前,就已經做好了充分的準備,當業務需要時,只需要增加服務器並簡單部署就可以了,技術團隊便可輕松應對了。

  在本篇的介紹中,有些核心的內容比如一致性Hash算法只是進行了簡單的介紹,並沒有深入的分析,這個源於我目前對其的理解還只是皮毛。等待我深入學習之後,我會抽空寫一篇單獨介紹一致性Hash算法的博文,並使用C#進行一個粗略的實現,有興趣的朋友敬請期待吧。

  另外,前面幾篇博文中有些園友提出介紹一些實踐性質的東西,我在這裏表示抱歉,因為本書只是單純地講解理論,而且也沒有深入地去講解這些理論,只是單純地擴展知識面,管中窺豹,一覽大型網站的技術體系。而我本人也還是一個即將求職和畢業的學生,在理論和實踐上都缺乏相應的經驗,但我會在精讀完本書後去做一些相應場景的具體實踐,比如使用Memcached或Redis構建分布式緩存集群,使用Mono在Linux下搭建ASP.NET MVC應用環境,使用高性能的Nginx或Jexus服務器構建反向代理負載均衡服務器環境,使用發布訂閱模式實現MS SQL的讀寫分離實踐等等,如果園友有興趣的話,也可以自行找資料去做相關實踐。如果覺得喜歡我的博文,那我只能說敬請期待了(現在時間寶貴啊,馬上要找工作了,還得復習復習,再過段時間畢業論文的鴨梨又要來了,我勒個去),麽麽嗒。

參考文獻

  (1)李智慧,《大型網站技術架構-核心原理與案例分析》,http://item.jd.com/11322972.html

  (2)老徐的私房菜,《HTTP無狀態協議和Session原理》,http://laoxu.blog.51cto.com/4120547/1219699

  (3)百度百科,《一致性Hash算法》,http://baike.baidu.com/view/1588037.htm

  (4)charlee,《Memcached完全剖析》,http://kb.cnblogs.com/page/42731/

  (5)bluishglc,《數據庫Sharding的基本思想和切分策略》,http://blog.csdn.net/bluishglc/article/details/6161475

本章思維導圖

技術分享

作者:周旭龍

出處:http://www.cnblogs.com/edisonchou/

本文版權歸作者和博客園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接。

《大型網站技術架構》讀書筆記之六:永無止境之網站的伸縮性架構