系統設計:設計類似 WhatsApp 的應用
在這個系統設計場景中,我們被要求設計一個類似 WhatsApp 的消息應用程序。
雖然在實際的討論中可能會重點討論該應用程序的一個或多個功能,但在本文中,我們將對系統的架構進行一個高層次的概述,然後可以根據需要深入探討具體的領域。
明確功能需求
通過向業務方提問來縮小範圍,因爲在一個小時內設計整個 WhatsApp 平臺是不現實的:
• 主要用例: 該應用的主要目的是發送、檢查和接收消息,以及閱讀和標記消息爲已讀。• 羣組: 我們將不涉及羣組消息,只考慮一對一消息。• 內容類型: 我們只支持文本消息,不支持圖片或視頻。
明確非功能需求
規模: 首先,我們來談談規模,即系統的大小和消息的處理量。假設每天發送 100 億條消息,並且我們計劃在一年內將其翻倍。
可用性: 在可用性方面,我們希望系統高度可用並始終運行。
延遲: 至於系統延遲,我們希望它幾乎是即時的,因此大多數 API 請求應在 100 毫秒內完成。
估算:數據計算
每天 100 億條消息,約爲 10B 消息 / 86,400 秒每天 = 115,740 條消息每秒(MPS)。在一年內翻倍意味着我們應計劃爲 115,740 * 2 = 231,480 MPS。
假設每條消息 200 字節,每日存儲量爲 10B 消息 * 200 字節 = 2 TB。年存儲量及增長約爲 2TB * 365 天 * 2 = 1.5 PB。
需要注意的是,我們計算的是平均值,但系統需要處理高峯流量,這可能比平均 MPS 高得多。我們可能需要根據高峯時間進行擴展。
接口 API 設計
我們可能會使用 RESTful API 風格以獲得更廣泛的兼容性。以下是可能的端點細分:
- 發送消息 (POST /messages): 請求體包括接收者的 ID 和消息內容。成功響應(200)返回唯一的消息標識符。錯誤代碼(400, 500)處理缺少參數或服務器問題。2. 檢查新消息 (GET /messages): 響應爲包含未讀消息的數組(200)或如果沒有則返回 204。3. 獲取特定消息 (GET /messages/:messageId): 返回特定消息(200)或未找到則返回 404。4. 標記消息爲已讀 (PUT 或 PATCH /messages/:messageId): 成功響應(200)確認更改,而 404 表示未找到消息。
其他考慮: 我們將集成 WebSockets 以實現實時更新。API 將處理認證和初始連接建立。並且分頁可能是‘檢查新消息’端點所需的。安全措施,如輸入驗證,也是必要的。
系統設計
移動應用: 用戶的主要界面將是移動應用(iOS, Android)。此應用程序處理發送和接收消息、聯繫人管理和對話。
負載均衡器: 爲了有效處理傳入請求,我們將使用負載均衡器來分配流量到多個服務器。這樣可以提高應用程序的可靠性。
API 服務器: 所有請求將進入 API 服務器,這些服務器處理我們之前概述的 RESTful API,管理消息邏輯。API 服務器本身可以是無狀態的,這樣我們可以水平擴展(添加更多服務器)以應對流量增長。
WebSocket 連接: 類似 WhatsApp 的應用程序嚴重依賴 WebSockets 進行實時通信。聊天服務器將與移動應用程序保持持久的 WebSocket 連接。當消息到達時,可以立即推送到接收者的設備。
消息分發器: 接下來,我們將有一個消息分發器服務,該服務的主要目的是將 API 服務器與直接數據庫寫入解耦,這對於處理高寫入量尤其重要。
消息隊列,如 Kafka 或 RabbitMQ,是這裏的理想選擇。其工作原理如下:
1.API 服務器接收到 “發送消息” 的 POST 請求。2. 它將消息放在隊列中,並迅速向客戶端返回成功 / 確認。3. 獨立的工作進程異步從隊列中讀取並將消息寫入數據庫。
數據庫 (NoSQL): 我們同意最終一致性是可以接受的,這使得 NoSQL 成爲高消息量的可擴展選擇。
以下是兩個強有力的選擇:
•Cassandra: 以可擴展性、高可用性和寫性能而聞名的寬列存儲。特別適合我們預期的高寫入量和簡單讀取模式(主要通過 ID 獲取消息)。•DynamoDB: AWS 提供的完全託管的鍵值和文檔數據庫。如果我們想要一個最小維護的數據庫解決方案且能輕鬆擴展,這非常有利。
分片和分區: 由於沒有單一數據庫可以處理我們 1.5 PB 的存儲需求,因此分片(水平分區)數據是至關重要的。
但是我們將如何分片和分區這些數據,以及這些 API 服務器如何知道從哪裏請求這些數據?
我們可以基於userId
進行分區。所有涉及用戶的消息將駐留在同一個分片 / 分區中。而我們的 API 服務器有兩種可能的方法來定位數據:
• 一致性哈希環: 數據位置可以基於分區鍵確定,允許 API 服務器直接路由請求到正確的數據庫分片。• 元數據服務: 一個獨立的服務保持分區鍵到分片位置的映射。API 服務器首先查詢此服務,然後進行數據庫調用。
結論和當前系統瓶頸
這概述了類似 WhatsApp 應用程序的主要架構。現在,讓我們看看我們當前系統中的潛在瓶頸和改進領域:
• 數據庫寫入: 高寫入量是一個潛在的瓶頸。分片、消息隊列和優化的數據庫選擇是關鍵。• 端到端加密: WhatsApp 模型非常強調安全性。實現端到端加密將是一個關鍵討論點。• 羣組聊天: 此功能爲消息路由和存儲帶來了額外的複雜性。• 媒體處理: 我們可以實現一個處理圖像和視頻上傳的系統,這裏使用壓縮以及多種存儲大小的縮略圖。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/5xHPSF07lDzBg6yxId4yRQ