
system-design
熱門使用結構化方法設計可擴展的分散式系統,涵蓋負載平衡、快取、資料庫擴展和訊息佇列。當使用者提到「系統設計」、「擴展這個」、「高可用性」、「速率限制器」、「設計 URL 縮短器」、「設計 Twitter」、「設計 Uber」、「設計新聞動態」、「系統設計面試」、「容量規劃」或「分散式架構」時使用。也適用於估算基礎設施需求、選擇微服務或單體架構,或為數百萬並發用戶設計系統。涵蓋常見系統設計(TinyURL、動態消息、聊天)和粗略估算。關於資料基礎知識,請參閱 ddia-systems。關於韌性,請參閱 release-it。
使用結構化方法設計可擴展的分散式系統,涵蓋負載平衡、快取、資料庫擴展和訊息佇列。當使用者提到「系統設計」、「擴展這個」、「高可用性」、「速率限制器」、「設計 URL 縮短器」、「設計 Twitter」、「設計 Uber」、「設計新聞動態」、「系統設計面試」、「容量規劃」或「分散式架構」時使用。也適用於估算基礎設施需求、選擇微服務或單體架構,或為數百萬並發用戶設計系統。涵蓋常見系統設計(TinyURL、動態消息、聊天)和粗略估算。關於資料基礎知識,請參閱 ddia-systems。關於韌性,請參閱 release-it。
系統設計框架
一種結構化方法,用於設計大規模分散式系統。在架構新服務、審查設計、估算容量或準備系統設計討論時,應用這些原則。
核心原則
從需求開始,而不是解決方案。 在了解限制條件之前就跳到架構,會產生過度設計或設計不足的系統。可擴展的系統是由熟悉的建構區塊(負載平衡器、快取、佇列、資料庫、CDN)組合而成——技巧在於選擇正確的區塊、透過估算來調整大小,並承擔每個選擇帶來的取捨。
評分
目標:10/10。 根據設計滿足多少個快速診斷列來評分——score = round(passed / 8 × 10):9-10 = 全部或幾乎全部列通過——明確的需求、實際的估算、冗餘、明確的資料庫擴展和快取策略、透過佇列的非同步處理、監控、部署計畫,並指出取捨;5-6 = 設計可行但跳過估算、冗餘或運維;<=3 = 在需求或估算之前就提出架構。始終說明當前分數、指出未通過的診斷列,並給出每個問題的具體修正。
系統設計框架
建構可靠、可擴展分散式系統的六個領域:
1. 四步驟流程
核心概念: 每個設計都遵循四個階段:(1) 理解問題並確定範圍,(2) 提出高層級設計並獲得認可,(3) 深入關鍵元件,(4) 總結取捨和未來改進。
為什麼有效: 沒有結構,設計要麼停留在過於抽象,要麼迷失在過早的細節中。四個步驟按比例投入時間——先宏觀輪廓,再深入關鍵處。
關鍵見解:
- 步驟 1(約 5-10 分鐘):釐清問題、功能和非功能需求、商定規模(DAU、QPS、儲存)
- 步驟 2(約 15-20 分鐘):高層級圖表,包含 API、服務、資料儲存、資料流箭頭
- 步驟 3(約 15-20 分鐘):詳細設計 2-3 個最困難或最關鍵的元件
- 步驟 4(約 5 分鐘):取捨、瓶頸、未來改進
- 絕不跳過步驟 1——模糊的範圍會浪費所有後續工作;明確取得假設的共識
程式碼應用:
| 情境 | 模式 | 範例 |
|---|---|---|
| 新服務啟動 | 在編碼前撰寫涵蓋所有四個步驟的一頁設計文件 | 需求、API 合約、資料模型、容量估算,然後實作 |
| 架構審查 | 依序引導審查者通過步驟 | 範圍、圖表、深入風險最高的元件、開放問題 |
| 事件事後檢討 | 透過四個步驟的視角追蹤失敗 | 哪個需求被忽略?哪個區塊失敗?哪個取捨導致問題? |
請參閱 references/four-step-process.md 以進行端到端設計——每個階段的時間分配、範例釐清問題,以及四個步驟的提示。
2. 粗略估算
核心概念: 使用二的冪次、延遲數字和簡單算術,在確定架構之前估算 QPS、儲存、頻寬和伺服器數量。
為什麼有效: 估算可防止過度配置(浪費金錢)和配置不足(負載下停機)。2 分鐘的計算可以節省數週的重工。
關鍵見解:
- 二的冪次:2^10 ≈ 1 千,2^20 ≈ 1 百萬,2^30 ≈ 10 億,2^40 ≈ 1 兆
- 延遲:記憶體讀取 ~100 ns,SSD 讀取 ~100 us,磁碟搜尋 ~10 ms,同資料中心往返 ~0.5 ms,跨洲 ~150 ms
- 可用性九個九:99.9% = 每年 8.77 小時停機;99.99% = 每年 52.6 分鐘
- QPS:DAU x 每日動作數 / 86,400 秒;尖峰通常是平均的 2-5 倍
- 儲存:每日記錄數 x 記錄大小 x 保留期限
- 大膽取整——目標是數量級,而非精確度
程式碼應用:
| 情境 | 模式 | 範例 |
|---|---|---|
| 容量規劃 | 估算 QPS,乘以成長因子 | 1 億 DAU x 5 動作 / 86400 = 約 5,800 QPS 平均,約 30K 尖峰 |
| 儲存預算 | 每筆記錄大小 x 數量 x 保留期限 | 5 億推文/天 x 300 位元組 x 365 天 = 約 55 TB/年 |
| SLA 定義 | 將九個九轉換為允許停機時間 | 四個九 = 每年約 52 分鐘停機 |
請參閱 references/estimation-numbers.md 以調整系統規模——完整的延遲表、可用性九個九表,以及 QPS/儲存/頻寬計算範例。
3. 建構區塊
核心概念: 可擴展系統由標準工具組裝而成:DNS、CDN、負載平衡器、反向代理、應用伺服器、快取、訊息佇列和一致性雜湊。
為什麼有效: 每個區塊以一種成本換取另一種(快取以新鮮度換取讀取速度;佇列以延遲換取解耦),因此只在出現特定瓶頸時引入區塊——一開始就全部加入只會增加故障模式。
關鍵見解:
- 負載平衡器:L4(傳輸層——快速、簡單)vs L7(應用層——內容感知路由)
- 快取層:客戶端、CDN、網頁伺服器、應用程式(Redis/Memcached)、資料庫查詢快取
- 快取策略:cache-aside(應用管理)、read-through、write-through(同步)、write-behind(非同步)
- 訊息佇列(Kafka、RabbitMQ、SQS):解耦生產者和消費者、吸收尖峰、啟用非同步處理
- 一致性雜湊:在節點變化時以最小重新分配方式將鍵分佈到節點
程式碼應用:
| 情境 | 模式 | 範例 |
|---|---|---|
| 讀取密集型工作負載 | 在資料庫前使用 cache-aside Redis | 快取使用者設定檔並設定 TTL;寫入時失效 |
| 流量尖峰 | API 和工作器之間的訊息佇列 | 將圖片調整大小任務排入佇列;工作器以自己的節奏拉取 |
| 全球用戶 | 靜態資源的 CDN | 從邊緣提供 JS/CSS/圖片;來源僅提供 API |
| 不均勻負載 | 分片分配的一致性雜湊 | 新增節點僅移動約 1/n 的鍵 |
請參閱 references/building-blocks.md 以選擇元件——DNS、CDN、負載平衡器、快取策略、訊息佇列和一致性雜湊的運作方式及何時引入。
4. 資料庫設計與擴展
核心概念: 根據資料形狀和存取模式選擇 SQL 或 NoSQL;先垂直擴展,當垂直限制達到時再水平擴展(複寫和分片)。
為什麼有效: 資料庫通常是第一個瓶頸。理解複寫、分片和反正規化的取捨,可以延緩昂貴的重新架構,並使成長更有計畫。
關鍵見解:
- 垂直擴展較簡單但有上限;水平擴展較困難但幾乎無限
- 複寫:主從(一個寫入器,多個讀取器)適用於讀取密集型;多主適用於多區域寫入
- 分片:基於雜湊(均勻分佈,範圍查詢困難)、基於範圍(範圍容易,熱點風險)、基於目錄(靈活,額外查詢)
- SQL 適用於 ACID 交易、聯結、定義的結構;NoSQL 適用於靈活結構、水平擴展、極高寫入吞吐量
- 反正規化以儲存和寫入複雜度換取讀取速度——當讀取主導且資料變化不頻繁時使用
- 名人/熱點問題:一個熱門分片需要次要分割或快取層
程式碼應用:
| 情境 | 模式 | 範例 |
|---|---|---|
| 讀取密集型 API | 主從架構搭配讀取副本 | 讀取到副本,寫入到主節點;接受些微延遲 |
| 大規模使用者資料 | 基於 user_id 的雜湊分片 | hash(user_id) % num_shards;均勻、獨立的分片 |
| 分析儀表板 | 反正規化的具體化視圖 | 夜間預先聯結和彙總;從具體化表格提供服務 |
請參閱 references/database-scaling.md 以處理資料庫瓶頸——複寫拓撲、三種分片策略比較、反正規化取捨,以及 SQL 與 NoSQL 選擇指南。
5. 常見系統設計
核心概念: 大多數系統是少數已知設計的變體:URL 縮短器、速率限制器、通知系統、新聞動態、聊天、搜尋自動完成、網頁爬蟲、唯一 ID 產生器。
為什麼有效: 一個已知設計的心智庫,讓你能辨識新問題類似哪種模式並加以調整,而不是從頭發明。
關鍵見解:
- URL 縮短器:base62 編碼、鍵值儲存、301 vs 302 重新導向取捨(快取 vs 分析)
- 速率限制器:在閘道使用 token bucket 或 sliding window;回傳 429 並附上 Retry-After
- 新聞動態:寫入時扇出(發文時推送)vs 讀取時扇出(閱讀時拉取);名人使用混合模式
- 聊天:WebSocket 用於即時雙向訊息、佇列用於傳遞保證、心跳存在服務
- 自動完成:前 k 個熱門查詢的 Trie;預先計算並快取熱門前綴
- 網頁爬蟲:BFS 搭配 URL frontier、禮貌性(robots.txt、每個網域速率限制)、透過內容雜湊去重
- 唯一 ID:UUID(簡單、無需協調)vs Snowflake(64 位元、可依時間排序、感知資料中心)
程式碼應用:
| 情境 | 模式 | 範例 |
|---|---|---|
| 短連結服務 | Base62 編碼自動增量 ID 或雜湊 | https://short.ly/a1B2c3 對應到一個鍵值行 |
| API 保護 | 閘道的 token bucket | 每個金鑰每分鐘 100 個 token;穩定補充;拒絕時回傳 429 |
| 社交動態 | 混合扇出 | 為粉絲數 <10K 的帳號預先計算動態;閱讀時合併名人貼文 |
請參閱 references/common-designs.md 以處理類似已知設計的問題——URL 縮短器、速率限制器、新聞動態、聊天、自動完成、網頁爬蟲和唯一 ID 產生器的完整逐步解說。
6. 可靠性和運維
核心概念: 系統的好壞取決於其維持運作、復原和可觀察的能力。健康檢查、監控、日誌記錄和部署策略是首要的設計考量,而非事後才想到。
為什麼有效: 生產系統會以圖表從未預測的方式失敗。運維就緒——指標、警報、回滾計畫、冗餘——決定了故障是短暫問題還是停機事件。
關鍵見解:
- 健康檢查:存活(程序是否活著?)和就緒(能否處理流量?)——Kubernetes 兩者都使用
- 可觀察性的三大支柱:指標(Prometheus、Datadog)、日誌(ELK、CloudWatch)、追蹤(Jaeger、Zipkin)
- 部署:滾動(逐步)、藍綠(在相同環境間即時切換)、金絲雀(先小比例)
- 災難復原:RPO(可接受的資料遺失)和 RTO(可接受的復原時間)驅動備份和容錯移轉策略
- 多資料中心:主動-被動(容錯移轉)或主動-主動(需要資料同步和衝突解決)
- 自動擴展:根據 CPU、記憶體、佇列深度或自訂指標擴展;始終設定最小和最大數量
程式碼應用:
| 情境 | 模式 | 範例 |
|---|---|---|
| 零停機部署 | 藍綠部署搭配健康檢查閘道 | 檢查通過後切換到綠色;保留藍色作為即時回滾 |
| 逐步推出 | 金絲雀部署搭配指標比較 | 5% 流量到新版本;比較錯誤和延遲;推廣或回滾 |
| 資料安全 | 定義 RPO/RTO 並據以實作 | RPO 1 小時 = 每小時備份;RTO 5 分鐘 = 自動容錯移轉 |
請參閱 references/reliability-operations.md 以強化生產環境——健康檢查模式、可觀察性支柱、部署策略、災難復原(RPO/RTO)和自動擴展。
常見錯誤
| 錯誤 | 為什麼失敗 | 修正 |
|---|---|---|
| 在需求之前先有架構 | 解決錯誤的問題,忽略限制條件 | 花前 5-10 分鐘確定範圍:功能、規模、SLA |
| 沒有估算 | 配置數量級錯誤 | 在選擇元件前估算 QPS、儲存、頻寬 |
| 單點故障 | 一個元件拖垮整個系統 | 每一層都冗餘:多伺服器、多可用區、多區域 |
| 過早分片 | 在需要之前就引入巨大的運維複雜度 | 先垂直擴展、讀取副本、積極快取、最後分片 |
| 快取沒有失效策略 | 過時資料導致錯誤和混亂 | 定義 TTL;cache-aside 搭配寫入時明確失效 |
| 到處都是同步呼叫 | 一個慢服務將延遲串聯到所有呼叫者 | 非延遲關鍵路徑使用佇列;同步呼叫設定逾時 |
| 忽略熱點 | 一個分片或鍵被大量使用,其他閒置 | 偵測熱鍵;加入次要分割或本地快取 |
| 沒有監控或警報 | 使用者比你更早發現故障 | 從第一天起就收集指標、日誌和追蹤 |
快速診斷
| 問題 | 如果否 | 行動 |
|---|---|---|
| 是否列出功能和非功能需求? | 設計基於假設 | 寫下功能、DAU、QPS、儲存、延遲和可用性 SLA |
| 是否有 QPS 和儲存估算? | 容量是猜測 | DAU x 動作 / 86400 計算 QPS;記錄 x 大小 x 保留期限計算儲存 |
| 每個元件是否都有冗餘? | 單點故障 | 為每個元件加入副本、容錯移轉或多可用區 |
| 是否定義了資料庫擴展策略? | 成長時會撞牆 | 先垂直擴展,然後讀取副本,最後用明確的分片鍵進行分片 |
| 讀取密集型路徑是否有快取? | 資料庫承受不必要的負載 | Redis/Memcached cache-aside 搭配定義的 TTL |
| 非同步路徑是否使用佇列? | 緊耦合、串聯故障 | 使用 Kafka/SQS 解耦任務、通知、分析 |
| 是否有監控和警報計畫? | 對生產故障一無所知 | 定義指標、日誌彙總、追蹤、警報閾值 |
| 是否定義了部署策略? | 一次性發布風險高 | 滾動、藍綠或金絲雀部署,搭配自動回滾 |
延伸閱讀
如需包含詳細圖表和逐步解說的完整指南:
- 《System Design Interview -- An Insider's Guide》 by Alex Xu(第一冊)
- 《System Design Interview -- An Insider's Guide: Volume 2》 by Alex Xu(第二冊)
- 《Designing Data-Intensive Applications》 by Martin Kleppmann(資料系統基礎)
- ByteByteGo -- Alex Xu 的平台,提供視覺化系統設計解說
關於作者
Alex Xu 是一位軟體工程師,曾服務於 Twitter、Apple 和 Oracle,也是 ByteByteGo 的創辦人。他的兩冊《System Design Interview》系列銷量超過 50 萬本,透過結構化思考、估算和清晰溝通,將系統設計轉變為可學習、可重複的技能。



