可伸縮設計
系統的伸縮性是架構中最重要的技術,即使用伺服器的叢集功能,透過不斷向叢集中新增伺服器來增強整個叢集的處理能力。
“伸”即架構的規模和伺服器的規模不斷擴大。
架構的伸縮性設計
架構的伸縮性設計可以分成兩類,一類是根據功能進行物理分離實現伸縮,另一類是單一功能透過叢集實現伸縮。前者是不同的伺服器部署不同的服務,提供不同的功能;後者是叢集內的多臺伺服器部署相同的服務,提供相關的功能。
架構的物理分離分為如下兩種。
◎ 紝向分離:根據功能模型的不同將系統分離,一般分為展示層、應用層、服務層和資料層。
◎ 橫向分離:根據業務模型的不同,可以將業務紝向進行分離。
對叢集規模的調整指透過負載均衡動態增減伺服器的數量,如圖5.9所示。
圖5.9
應用服務的伸縮性設計
應用伺服器的伸縮性,指的是HTTP請求分發裝置可以感知或者配置叢集的伺服器數量,還可以及時發現叢集中新上線或下線的伺服器,並能向新上線的伺服器分發請求,停止向已下線的伺服器分發請求。這種HTTP請求分發裝置被稱為負載均衡伺服器。
負載均衡是網站必不可少的基礎技術,不但可以實現網站的伸縮性,還可以改善網站的可用性,是網站的重要技術。負載均衡的具體技術實現也多種多樣,從硬體實現到軟體實現,從商業產品到開源,應有盡有,但實現負載均衡的基礎技術不外乎如下幾種。
(1)HTTP 重定向負載均衡。HTTP 重定向伺服器是一臺普通的應用伺服器,其唯一功能就是根據使用者的 HTTP 請求計算出一臺真實的伺服器地址,並將該伺服器地址寫入HTTP 重定向響應中(重定向響應狀態碼為 302)返回給使用者的瀏覽器。使用者的瀏覽器在收到響應之後,根據返回的資訊重新發送一個請求到真實的伺服器上。
(2)DNS域名解析負載均衡。在利用DNS處理域名解析請求的同時進行負載均衡是另一種常用的方案。每次域名解析請求都會根據負載均衡演算法計算一個不同的 IP 地址並返回,這樣在 A 記錄中配置的多臺伺服器就構成了一個叢集,可以實現負載均衡。DNS域名解析負載均衡的優點是將負載均衡工作交給DNS,省略了網路管理的麻煩,缺點就是DNS可能快取A記錄,不受網站控制。事實上,大型網站總是部分使用DNS域名解析,作為第1級負載均衡手段,再在內部做第2級負載均衡。
(4)IP負載均衡。指網路層透過修改請求目標地址進行負載均衡,在使用者請求資料包到達負載均衡伺服器後,負載均衡伺服器在作業系統核心獲取網路資料包,根據負載均衡演算法計算得到一臺真實的We b伺服器的地址,然後將資料包的I P地址修改為真實的We b伺服器的地址,不需要透過使用者程序處理。在真實的 We b 伺服器處理完畢後,相應的資料包回到負載均衡伺服器,負載均衡伺服器再將資料包源地址修改為自身的 IP 地址傳送給使用者的瀏覽器。
這裡的關鍵在於真實的 We b 伺服器的相應資料包如何返回給負載均衡伺服器:一種方案是負載均衡伺服器在修改目標 IP 地址的同時修改源地址,將資料包源地址改為自身的IP,即源地址轉換(SNAT);另一種方案是將負載均衡伺服器同時作為真實物理伺服器的閘道器伺服器,這樣所有的資料都會到達負載均衡伺服器。
IP負載均衡在核心程序中完成資料分發,較反向代理均衡有更好的處理效能。但由於所有請求響應的資料包都需要經過負載均衡伺服器,因此負載均衡的網絡卡頻寬成為系統的瓶頸。
(5)資料鏈路層負載均衡。這種資料傳輸方式又被稱為三角傳輸模式,負載均衡資料在分發過程中不修改IP地址,只修改目標MAC地址,透過將真實物理伺服器叢集所有機器的虛擬IP地址和負載均衡伺服器的IP地址配置為一致的IP地址,來達到負載均衡,這種負載均衡方式又被稱為直接路由方式。在使用者的請求到達負載均衡伺服器後,負載均衡伺服器將請求資料的目標MAC地址修改為真實的Web伺服器的MAC地址,不修改資料包目標I P地址,因此資料可以正常到達目標Web伺服器,該伺服器在處理完資料後可以經過網管伺服器而不是負載均衡伺服器直接到達使用者的瀏覽器。
分散式快取的伸縮性設計
在分散式快取伺服器叢集中,不同伺服器中的快取資料並不相同,對快取的訪問請求,不能在快取伺服器叢集中的任意一臺上處理,必須先找到快取中有需要資料的伺服器,才能進行訪問。這會嚴重製約分散式快取叢集的伸縮性設計,因為新上線的快取伺服器沒有快取資料,而已下線的快取伺服器還快取著網站的許多熱點資料。
分散式快取叢集伸縮性設計的最主要目標就是讓新上線的快取伺服器對整個分散式快取叢集的影響最小,也就是說在新加入快取伺服器後,應使在整個快取伺服器叢集中已經快取的資料儘可能被訪問到。
資料儲存的伸縮性設計
資料儲存伺服器叢集的伸縮性對資料的永續性和可用性都提出了更高的要求。具體來說,可以分為關係資料庫叢集的伸縮性設計和NoSQL資料庫的伸縮性設計。
在關係資料庫叢集的伸縮性設計中,主要的關係資料庫都支援資料複製功能,使用這個功能可以對資料庫進行簡單伸縮。另外,除了利用資料庫進行主從讀寫分離,也可以利用業務分隔模式使不同業務的資料表部署在不同的資料庫叢集上,即資料分庫。但這種方式的制約條件是跨庫不能進行Join操作。在大型網站的實際應用中,即使使用了分庫和主從複製,對一些單表資料量很大的表還需要進行分片,
將一張表拆開且分別儲存在多個數據庫中。
NoSQL 主要指非分散式的非關係資料庫設計模式。一般而言,NoSQL 資料庫產品都放棄了關係資料庫的兩大重要基礎:以關係代數為基礎的結構化查詢語言(SQL)和事物一致性保證(ACID),但是強化了高可用性和可伸縮性。
可擴充套件性設計擴充套件性是指在對現有系統影響最小的情況下,系統功能可持續擴充套件或提升的能力。設計架構可擴充套件的核心思想是模組化,並在此基礎上降低模組間的耦合性,提供模組的複用性。對模組透過分散式部署,將獨立的模組部署在獨立的伺服器上(叢集),從物理上分離模組之間的耦合關係。模組在分散式部署後的具體聚合方式主要有分散式訊息和分散式服務這兩種。
透過訊息降低系統的耦合性
如果在模組之間不存在直接呼叫,那麼新增模組或者修改模組對其他模組影響最小,這樣系統的可擴充套件性無疑更好一些。事件驅動框架指透過在低耦合的模組之間傳輸事件訊息,以保持模組的鬆散耦合,並藉助事件訊息的通訊完成模組間的合作,典型的架構就是生產者消費者模式。在大型網站架構中具體的實現手段很多,最常用的就是分散式訊息佇列,訊息佇列利用釋出-訂閱模式工作:訊息傳送者釋出訊息,一個或者多個訊息接收者訂閱訊息。由於訊息傳送者不需要等待訊息接收者處理資料就可以返回,所以系統具有更好的響應延遲;同時,在網站訪問高峰期間,訊息可以被暫時儲存在訊息佇列中等待處理,減輕了資料庫等後端儲存的負載壓力。
透過分散式服務提供可複用的業務
使用分散式服務是降低系統耦合性的另一個重要手段。例如,分散式訊息佇列透過訊息規避系統的耦合性,由不同的子系統處理同一個訊息;分散式服務則透過介面分解系統的耦合性,不同的子系統透過相同的介面描述進行服務呼叫。大型系統的分散式服務的需求與特點為:負載均衡、失效轉移、高效的遠端通訊、整合異構系統、對應用最小入侵、版本管理和實時監控。
目前,國內有較多成功實施案例的開源分散式服務框架是阿里巴巴的Dubbo,服務消費程式透過服務介面使用服務,而服務介面透過代理載入具體服務,具體服務可以是本地的程式碼模組,也可以是遠端的服務,因此對應用入侵較小;應用程式需要呼叫服務介面,服務框架則根據配置自動呼叫本地或遠端實現。
服務框架的客戶端模組透過服務註冊中心載入服務提供者列表(服務提供者在啟動後主動向服務註冊中心註冊自己可提供的服務介面列表),查詢需要的服務介面,並根據配置的負載均衡策略將服務呼叫請求傳送到某臺服務提供者的伺服器。如果服務呼叫失敗,則客戶端模組會自動從服務提供者列表中選擇一個可提供同樣服務的另一臺伺服器重新請求服務,實現服務的自動失效轉移,保證高可用服務。
建立開放平臺
大型系統為了更好地服務自己的使用者,開放了更多的增值服務,會將系統內部的服務封裝成一些呼叫介面開放出去,供外部的第三方開發者使用,這種提供開放介面的平臺被稱作開放平臺。開放平臺是系統內部和外部互動的介面,在外部需要面對眾多的第三方開發者,在內部需要面對系統內諸多的業務服務。雖然每個系統的業務場景和需求都不相同,但開發平臺的架構設計大同小異。開發平臺的要求如下。
◎ API 介面:是開發平臺暴露給開發者使用的一組 API,其形式可以是 RESTful、WebService和RPC等形式。
◎ 協議轉換:將各種 API 輸入轉換成內部服務可以識別的形式,並將內部服務的返回封裝成API格式。
◎ 安全:除了一般應用需要的身份識別、許可權控制等安全手段,開放平臺還需要配置分級的訪問頻寬限制,以保證資源被公平合理地使用。
◎ 審計:記錄第三方應用的訪問情況並進行監控、計費等。
◎ 路由:將開放平臺的各種訪問路由對映到具體的內部服務。
◎ 流程:將一組離散的服務組織成一個上下文相關的新服務,隱藏服務的細節,提供統一的介面供開發者呼叫。