系統(tǒng)設(shè)計:隨用戶擴展的策略
單服務(wù)器設(shè)置
在單服務(wù)器設(shè)置中,所有內(nèi)容都運行在一臺服務(wù)器上。這包括網(wǎng)頁應(yīng)用程序、數(shù)據(jù)庫、緩存等。
圖1.1 請求流程
- 最終用戶通過域名(myurl.com)訪問網(wǎng)站。請求發(fā)送到 DNS,將域名映射到 IP 地址。
- IP 地址返回給網(wǎng)頁瀏覽器或移動應(yīng)用程序。
- HTTP 請求直接發(fā)送到 web 服務(wù)器。
- Web 服務(wù)器然后將請求的資源返回給客戶端。在上圖中,返回 HTML 頁面進行渲染。
圖中使用的組件定義如下:
- Web 服務(wù)器:一臺能夠通過互聯(lián)網(wǎng)向最終用戶提供網(wǎng)頁內(nèi)容的計算機系統(tǒng)。它包括網(wǎng)頁服務(wù)器軟件和網(wǎng)站組件文件,如 HTML 文檔、圖像、CSS 樣式表、JavaScript 文件等。
- Web 客戶端(Web/移動):用于通過 HTTP 連接到 Web 服務(wù)器的客戶端應(yīng)用程序。通常是一個網(wǎng)頁瀏覽器或 Web 應(yīng)用程序,用于顯示從服務(wù)器接收的網(wǎng)頁并允許用戶與 Web 服務(wù)器進行交互。
- 域名系統(tǒng)(DNS):充當互聯(lián)網(wǎng)的電話簿。人們通過域名(google.com)訪問信息,但 Web 服務(wù)器使用互聯(lián)網(wǎng)協(xié)議(IP)地址進行交互。DNS 將域名轉(zhuǎn)換為 IP 地址,以便瀏覽器可以加載互聯(lián)網(wǎng)資源?;ヂ?lián)網(wǎng)中的每個設(shè)備都有唯一的 IP 地址,其他機器使用該地址查找設(shè)備。通常,DNS 是由第三方提供的付費服務(wù),不由 Web 服務(wù)器托管。
將數(shù)據(jù)庫與 Web 服務(wù)器分離
隨著用戶數(shù)量的增長,為了更獨立地擴展,第一步是將數(shù)據(jù)庫與 Web 服務(wù)器分離。
圖1.2 請求流程
- 最終用戶通過域名(myurl.com)訪問網(wǎng)站。請求發(fā)送到 DNS,將域名映射到 IP 地址。
- IP 地址返回給網(wǎng)頁瀏覽器或移動應(yīng)用程序。
- HTTP 請求直接發(fā)送到 web 服務(wù)器。
- Web 服務(wù)器向數(shù)據(jù)庫服務(wù)器發(fā)送請求,執(zhí)行讀取、寫入或更新數(shù)據(jù)操作。
- 數(shù)據(jù)從數(shù)據(jù)庫服務(wù)器返回到 web 服務(wù)器。
- 數(shù)據(jù)在 web 服務(wù)器中處理,最終返回給 Web 客戶端。
圖中新增的組件定義如下:
- 數(shù)據(jù)庫:存儲在計算機系統(tǒng)中的結(jié)構(gòu)化或非結(jié)構(gòu)化信息集合。數(shù)據(jù)庫的選擇取決于存儲的信息類型。數(shù)據(jù)庫可以從傳統(tǒng)關(guān)系型數(shù)據(jù)庫到非關(guān)系型數(shù)據(jù)庫等各種類型。
- 傳統(tǒng)關(guān)系型數(shù)據(jù)庫:以表、行和列的方式結(jié)構(gòu)化信息。關(guān)系型數(shù)據(jù)庫能夠通過連接表之間的關(guān)系來建立鏈接,這使得理解和獲取有關(guān)各種數(shù)據(jù)點關(guān)系的見解變得容易。常見的傳統(tǒng)數(shù)據(jù)庫有 MySQL、Oracle 數(shù)據(jù)庫、PostgreSQL 等。
- 非關(guān)系型數(shù)據(jù)庫:也稱為 NoSQL 數(shù)據(jù)庫,使用針對存儲的數(shù)據(jù)類型的特定要求進行優(yōu)化的存儲模型。它可以進一步分為多種不同的類別,如鍵值存儲、圖形存儲、列存儲、文檔存儲等。一些常見的例子包括 Cassandra、MongoDB、Neo4j 等。
擴展 Web 服務(wù)器
隨著用戶基數(shù)的增長和流量的增加,擴展 Web 服務(wù)器的能力變得至關(guān)重要。擴展的方式有兩種,即垂直擴展和水平擴展。在垂直擴展中,通過向同一臺服務(wù)器添加更多 CPU、RAM 等來“擴展”,而在水平擴展中,通過向資源池中添加更多服務(wù)器來“擴展”。盡管垂直擴展在性質(zhì)上更加簡單,但它也有自己的局限性。其中一些限制包括硬件限制(無法向單個服務(wù)器添加無限制的內(nèi)存和 CPU),而且存在單點故障,這可能是一個巨大的缺點。因此,在大規(guī)模應(yīng)用程序的情況下,使用水平擴展可能是更好的選擇,通過負載均衡器將流量分布到多個服務(wù)器上。
負載均衡器:負載均衡器充當流量管理器,位于服務(wù)器前面,將客戶端請求路由到能夠滿足這些請求的所有服務(wù)器上,以最大化速度和容量利用率。負載均衡器的一些主要責(zé)任包括:
- 高效地將客戶端請求或網(wǎng)絡(luò)負載分布到多個服務(wù)器上。
- 僅將請求發(fā)送到在線的服務(wù)器,確保高可用性和可靠性。
- 根據(jù)需求靈活添加或移除服務(wù)器。
用戶直接連接到負載均衡器的公共 IP。在此架構(gòu)中,無法使用公共 IP 訪問 Web 服務(wù)器。負載均衡器使用私有 IP 與不同的服務(wù)器進行通信。私有 IP 僅用于在同一網(wǎng)絡(luò)內(nèi)進行通信。
一些常見的負載均衡算法:
- 輪詢法(Round Robin)— 順序分發(fā)請求。
- 最少連接法(Least Connections)— 發(fā)送到當前連接最少的服務(wù)器。
- 最少時間法(Least Time)— 發(fā)送到響應(yīng)最快且連接最少的服務(wù)器。
- 哈希法(Hash)— 根據(jù)您定義的鍵(如客戶端 IP 地址、URL 等)進行分發(fā)。
數(shù)據(jù)可用性和復(fù)制
擴展的最關(guān)鍵方面之一是增強數(shù)據(jù)的可用性和可靠性。數(shù)據(jù)復(fù)制是實現(xiàn)這一目標的重要方式,它通過在不同服務(wù)器上創(chuàng)建和維護數(shù)據(jù)庫的副本來實現(xiàn)。
在圖1.4中,我們可以看到原始(主)數(shù)據(jù)庫和副本(從)數(shù)據(jù)庫之間的主從關(guān)系。
- 主數(shù)據(jù)庫:僅支持來自 Web 服務(wù)器的寫入操作。所有修改數(shù)據(jù)的操作,如插入、刪除、更新,都必須發(fā)送到主數(shù)據(jù)庫。如果主數(shù)據(jù)庫下線,一個從數(shù)據(jù)庫將被提升為新的主數(shù)據(jù)庫。
- 從數(shù)據(jù)庫:僅支持來自 Web 服務(wù)器的讀取操作。通常情況下,從數(shù)據(jù)庫比主數(shù)據(jù)庫多,因為讀取和寫入的比例總是更高。如果從數(shù)據(jù)庫下線,一個新的從數(shù)據(jù)庫將取代舊的從數(shù)據(jù)庫。
數(shù)據(jù)復(fù)制的優(yōu)勢:
- 更好的性能 — 允許更多查詢并行處理。
- 可靠性 — 數(shù)據(jù)在多個服務(wù)器上復(fù)制。我們不需要擔(dān)心數(shù)據(jù)丟失。
- 高可用性 — 如果一個數(shù)據(jù)服務(wù)器下線,您可以從另一個數(shù)據(jù)庫訪問存儲的數(shù)據(jù)。
一些其他常見的數(shù)據(jù)復(fù)制類型:
- 主-主復(fù)制 — 對任何主數(shù)據(jù)庫進行的更改會復(fù)制到配置中的其他主數(shù)據(jù)庫。
- 快照復(fù)制 — 在特定時間點創(chuàng)建整個數(shù)據(jù)庫的副本,然后將快照復(fù)制到一個或多個目的地。
討論了 Web 層和數(shù)據(jù)層之后,我們將簡要介紹對改善負載/響應(yīng)時間起著關(guān)鍵作用的兩個其他概念:緩存和內(nèi)容傳遞網(wǎng)絡(luò)(CDN)。
緩存
緩存是一個臨時存儲區(qū),用于在內(nèi)存中存儲昂貴響應(yīng)的結(jié)果或頻繁訪問的數(shù)據(jù)。
- 緩存命中 — Web 服務(wù)器從緩存中請求數(shù)據(jù)。如果數(shù)據(jù)存在于緩存中,則為緩存命中。在這種情況下,無需向數(shù)據(jù)庫服務(wù)器發(fā)出網(wǎng)絡(luò)調(diào)用。
- 緩存未命中 — Web 服務(wù)器從緩存中請求數(shù)據(jù)。如果緩存中不包含數(shù)據(jù),則為緩存未命中。此時,需要從數(shù)據(jù)庫獲取數(shù)據(jù),然后將數(shù)據(jù)保存到緩存中。
使用緩存的一些關(guān)鍵考慮因素:
- 數(shù)據(jù)讀取頻率高于修改頻率。
- 實施良好的過期策略,這很重要,因為延遲的過期策略可能導(dǎo)致緩存中的數(shù)據(jù)過時,而頻繁的過期策略可能會降低緩存的效果,因為這會導(dǎo)致頻繁從數(shù)據(jù)庫重新加載數(shù)據(jù)。
- 為了減少故障,請考慮添加多個緩存服務(wù)器,以避免單點故障。
- 必須有一個良好的驅(qū)逐策略。一旦緩存已滿,為了添加新項目,現(xiàn)有項目應(yīng)根據(jù)驅(qū)逐策略進行刪除。
緩存的類型:
- 應(yīng)用程序服務(wù)器緩存 — 緩存與應(yīng)用程序服務(wù)器一起存儲在內(nèi)存中。在多 Web 服務(wù)器系統(tǒng)中,此架構(gòu)中的一個缺點是,每個服務(wù)器將不知道已緩存請求,因此會產(chǎn)生大量的緩存未命中。
- 分布式緩存 — 每個節(jié)點將擁有整個緩存空間的一部分,然后使用一致性哈希函數(shù)將每個請求路由到可找到緩存請求的地方。
- 全局緩存 — 您將擁有單個緩存空間,所有節(jié)點都將使用此單個空間。
內(nèi)容傳遞網(wǎng)絡(luò)(CDN)
CDN 是一個由地理位置分散的服務(wù)器網(wǎng)絡(luò),用于傳遞靜態(tài)內(nèi)容,包括圖像、視頻、CSS、JavaScript 文件等。CDN 由像亞馬遜、Akamai 等第三方提供商運行。
使用 CDN 的請求流程:
- 用戶通過 URL 請求資源。這些 URL 是由 CDN 提供商提供的。
- 如果 CDN 緩存中沒有資源,則從源(如亞馬遜 S3)請求。
- 源然后將資源返回給 CDN 服務(wù)器。
- CDN 緩存資源并將其返回給用戶。該圖像將在 TTL(存活時間)過期之前保留在緩存中。
- 當另一個用戶請求相同資源時,如果 TTL 尚未過期,則從緩存中獲取。
總之,與用戶規(guī)模的擴展不僅是技術(shù)上的挑戰(zhàn),更是現(xiàn)代數(shù)字系統(tǒng)的戰(zhàn)略必需品。從設(shè)計彈性架構(gòu)到實施有效的擴展策略,我們探討了確保您的系統(tǒng)可以與用戶需求無縫增長的關(guān)鍵要素。