System Design was HARD until I Learned these 30 Concepts|學會這 30 個概念後,系統設計不再困難

這部影片由 AlgoMaster 頻道製作,整理了系統設計中最重要的 30 個核心概念。從最基礎的 Client-Server 架構、DNS、HTTP 協議,到進階的資料庫擴展策略(Replication、Sharding)、快取、CDN、微服務與訊息佇列,涵蓋了系統設計面試和實際工程中反覆出現的關鍵知識。作者以自身在大型科技公司 8 年的經驗為基礎,將這些概念串聯成一個完整的學習路徑。


原影片連結:https://www.youtube.com/watch?v=s9Qh9fWeOAk

影片重點

  • Client-Server 架構是幾乎所有 Web 應用的基礎模型
  • DNS 將人類可讀的域名轉換為 IP 位址
  • Proxy 與 Reverse Proxy 在系統中扮演不同角色
  • HTTP/HTTPS 是客戶端與伺服器溝通的標準協議
  • REST 和 GraphQL 是兩種主流的 API 設計風格
  • SQL 和 NoSQL 各有適用場景,現代應用常混合使用
  • 垂直擴展有上限,水平擴展才是長期方案
  • 資料庫擴展有四大技術:Indexing、Replication、Sharding、Denormalization
  • 快取(Caching)和 CDN 是提升效能的關鍵手段
  • 微服務架構搭配 Message Queue 實現服務解耦

詳細內容

[00:00] Client-Server 架構

幾乎所有你使用的 Web 應用都建立在 Client-Server 架構之上。客戶端(Client)可以是瀏覽器、行動 App 或任何前端應用;伺服器(Server)則是一台持續運行的機器,等待處理傳入的請求。客戶端發送請求來儲存、讀取或修改資料,伺服器接收請求後進行處理,並回傳回應。

[01:10] IP 位址與 DNS

客戶端如何找到伺服器?在網路上,電腦透過 IP 位址互相識別,就像伺服器的電話號碼。但我們造訪網站時不會輸入 IP 位址,而是輸入域名。DNS(Domain Name System)負責將容易記憶的域名映射到對應的 IP 位址。當你在瀏覽器輸入域名時,電腦會向 DNS 伺服器查詢對應的 IP,然後用這個 IP 與伺服器建立連線。

[02:20] Proxy 與 Reverse Proxy

當你造訪網站時,請求不一定直接到達伺服器,有時會先經過 Proxy 或 Reverse Proxy。Proxy(正向代理)作為你的裝置與網路之間的中間人,它會隱藏你的 IP 位址,保護你的身份隱私。Reverse Proxy(反向代理)則相反,它攔截客戶端請求,根據預定義的規則將請求轉發到後端伺服器。

[03:00] Latency 與多資料中心部署

客戶端與伺服器通訊時總會有延遲。物理距離是延遲的最大原因之一。例如伺服器在紐約,但印度的用戶發送請求,資料需要穿越半個地球往返,這種往返延遲稱為 Latency。高延遲會讓應用感覺緩慢。解決方案之一是在全球多個資料中心部署服務,讓用戶連接到最近的伺服器。

[03:45] HTTP 與 HTTPS

客戶端和伺服器使用 HTTP 協議溝通,這就是為什麼大多數 URL 以 HTTP 或 HTTPS 開頭。客戶端發送的請求包含 Header(請求類型、瀏覽器資訊、Cookie 等)和有時包含 Body(如表單輸入)。HTTP 有一個重大安全漏洞——它以明文傳輸資料。HTTPS 透過 SSL/TLS 協議加密所有資料,即使被截獲也無法讀取或篡改。

[04:50] API:REST 與 GraphQL

HTTP 只是資料傳輸協議,並沒有定義請求應如何結構化。API(Application Programming Interface)作為中間層,讓客戶端無需關心底層細節就能與伺服器溝通。

REST 是最廣泛使用的 API 風格。它是無狀態的(每個請求獨立),一切都被視為資源(users、orders、products),使用標準 HTTP 方法(GET、POST、PUT、DELETE)。REST 簡單、可擴展、容易快取,但在複雜資料擷取時可能效率不佳——端點常回傳比需要更多的資料。

GraphQL 由 Facebook 在 2015 年推出,讓客戶端精確指定需要的資料。用 REST 取得用戶資料及其最近貼文可能需要多次請求,GraphQL 可以合併為一次查詢。但 GraphQL 在伺服器端需要更多處理,且不像 REST 那樣容易快取。

[06:50] 資料庫:SQL vs NoSQL

客戶端通常需要儲存或讀取資料。現代應用處理的資料量遠超記憶體所能有效處理的範圍,因此需要專用的資料庫伺服器。

SQL 資料庫以表格形式儲存資料,有嚴格的預定義 Schema,遵循 ACID 特性。適合需要強一致性和結構化關聯的應用,如銀行系統。

NoSQL 資料庫不需要固定 Schema,專為高擴展性和效能設計。資料模型包括 Key-Value Store、Document Store、Graph Database 和 Wide-Column Store。

許多現代應用會同時使用 SQL 和 NoSQL。

[08:30] 垂直擴展 vs 水平擴展

隨著用戶增長,請求量也隨之增加。垂直擴展(Vertical Scaling)是升級現有伺服器的 CPU、RAM 或儲存空間,讓單一機器更強大。但它有明顯限制:每台機器都有硬體上限、高規格伺服器指數級昂貴、單點故障風險。

水平擴展(Horizontal Scaling)則是增加更多伺服器來分擔負載。更多伺服器代表更多容量,系統能更有效地處理增長的流量。如果一台伺服器當機,其他伺服器可以接手,提升可靠性。

[09:50] Load Balancer

水平擴展帶來新挑戰:客戶端怎麼知道該連接哪台伺服器?Load Balancer(負載均衡器)位於客戶端和後端伺服器之間,作為流量管理者,將請求分配到多台伺服器。如果某台伺服器掛了,Load Balancer 會自動將流量重導到其他健康的伺服器。常見的負載均衡演算法包括 Round Robin、Least Connections 和 IP Hashing。

[10:40] 資料庫 Indexing

Indexing(索引)是加速資料庫讀取查詢最快速有效的方式之一。就像書末的索引頁,讓你直接跳到相關章節,而不用翻閱每一頁。索引儲存欄位值和指向實際資料行的指標。索引通常建立在頻繁查詢的欄位上,如 Primary Key、Foreign Key 和常用於 WHERE 條件的欄位。但索引會減慢寫入速度,因為每次資料變更都需要更新索引。

[11:50] 資料庫 Replication

當單一資料庫伺服器無法處理持續增長的讀取請求時,可以使用 Replication(複製)。架構上有一個 Primary(主要副本)負責所有寫入操作,多個 Read Replica(讀取副本)處理讀取查詢。寫入 Primary 的資料會被複製到 Read Replica 保持同步。Replication 改善讀取效能、提升可用性——如果 Primary 故障,Read Replica 可以晉升為新的 Primary。

[12:55] Sharding(分片)

當服務擁有數百萬用戶、資料達到 TB 級別時,單一資料庫伺服器終將不堪負荷。Sharding 將資料庫分割成更小、更易管理的部分(Shard),分佈到多台伺服器上。每個 Shard 包含總資料的子集,資料根據 Sharding Key(如 User ID)進行分配。Sharding 也稱為水平分區(Horizontal Partitioning),按行分割資料。

[13:45] Vertical Partitioning(垂直分區)

如果問題不是行數太多,而是欄位太多呢?Vertical Partitioning 按欄位分割資料庫。例如,一個用戶表格儲存了個人資料、登入記錄和帳單資訊,可以將其拆分為更小、更聚焦的表格。這樣每次查詢只需掃描相關欄位,減少不必要的磁碟 I/O。

[14:30] Caching(快取)

無論怎麼優化資料庫,從磁碟讀取資料總比從記憶體讀取慢。Caching 將頻繁存取的資料存入記憶體。最常見的快取策略是 Cache-Aside 模式:用戶請求資料時,先檢查快取;如果命中就直接回傳;如果未命中,從資料庫讀取後存入快取再回傳。為防止過期資料被回傳,會設定 TTL(Time To Live)。

[15:30] Denormalization(反正規化)

關聯式資料庫使用 Normalization 將資料拆分到不同表格以減少冗餘,但這引入了 JOIN 操作。隨著資料量增長,JOIN 會拖慢查詢。Denormalization 透過將相關資料合併到單一表格來減少 JOIN,即使這意味著某些資料會被重複儲存。適用於讀取密集型應用,但代價是增加儲存空間和更複雜的更新操作。

[16:30] CAP Theorem

當系統擴展到多台伺服器、多個資料庫和資料中心時,就進入了分散式系統的領域。CAP 定理指出,沒有任何分散式系統能同時實現以下三者:Consistency(一致性)、Availability(可用性)、Partition Tolerance(分區容錯性)。由於網路故障是不可避免的,我們必須在 CP(一致性 + 分區容錯)和 AP(可用性 + 分區容錯)之間做出選擇。

[17:15] Blob Storage 與 CDN

現代應用不只處理文字記錄,還需要處理圖片、影片、PDF 等大型檔案。傳統資料庫不適合儲存大型非結構化檔案,因此我們使用 Blob Storage(如 Amazon S3)。Blob 儲存在雲端的容器(Bucket)中,每個檔案有唯一的 URL。

但直接從 Blob Storage 串流影片可能很慢。CDN(Content Delivery Network)是一個全球分散式伺服器網路,根據用戶的地理位置提供內容。內容從最近的 CDN 伺服器提供,用戶體驗到更快的載入時間和最少的緩衝。

[18:50] WebSocket

大多數 Web 應用使用 HTTP 的請求-回應模型。但對於即時聊天、股票行情、線上多人遊戲等即時應用,HTTP 太慢且低效。用 HTTP 實現即時更新只能靠 Polling(頻繁輪詢),但大部分回應是空的,浪費頻寬。

WebSocket 允許客戶端和伺服器之間建立持久的雙向連線。伺服器可以隨時主動推送更新,客戶端也能即時發送訊息,無需輪詢。

[19:50] Webhook

WebSocket 實現的是客戶端與伺服器之間的即時通訊。但如果是伺服器需要通知另一個伺服器呢?例如用戶付款後,支付閘道需要即時通知你的應用。Webhook 讓伺服器在事件發生時,主動發送 HTTP POST 請求到另一個伺服器的指定 URL,而不是不斷輪詢 API 檢查事件是否發生。

[20:30] 微服務架構

傳統應用使用 Monolithic 架構,所有功能在一個大型程式碼庫中。對大型系統來說,Monolith 變得難以管理、擴展和部署。微服務架構將應用拆分為更小的獨立服務,每個 Microservice 負責單一職責、有自己的資料庫和邏輯,可以獨立擴展,透過 API 或 Message Queue 與其他服務溝通。

[21:15] Message Queue

當多個微服務需要溝通時,直接 API 呼叫並不總是高效的。同步通訊(等待即時回應)在大規模下擴展性差。Message Queue 讓服務非同步溝通:Producer 將訊息放入佇列,Queue 暫存訊息,Consumer 取出並處理訊息。這實現了服務解耦,提升擴展性,並防止內部服務過載。

[22:00] Rate Limiting 與 API Gateway

如何防止公開 API 被濫用?Rate Limiting 限制客戶端在特定時間範圍內的請求數量。例如每分鐘 100 次請求,超過限制就暫時封鎖並回傳錯誤。常見的限流演算法有 Fixed Window、Sliding Window 和 Token Bucket。

API Gateway 是一個集中式服務,處理認證、限流、日誌、監控、請求路由等功能。它作為所有客戶端請求的單一入口,將請求路由到適當的微服務。

[23:10] Idempotency(冪等性)

在分散式系統中,網路故障和重試很常見。如果用戶不小心重新整理付款頁面,系統可能收到兩次付款請求。Idempotency(冪等性)確保重複請求產生與單次請求相同的結果。做法是為每個請求分配唯一 ID,處理前先檢查該請求是否已被處理過——如果是,忽略重複請求;如果否,正常處理。

我的想法

這部影片的最大價值在於它提供了一個清晰的系統設計「知識地圖」。對初學者來說,系統設計最令人挫敗的不是單一概念有多難,而是不知道該學什麼、學到什麼程度。這 30 個概念基本上涵蓋了系統設計面試和實際工程中最常見的主題。

值得注意的是,影片從最底層的 Client-Server 開始,一路往上構建到微服務和分散式系統,這個學習順序本身就很有參考價值。每個概念的引入都是因為前一個概念遇到了瓶頸——需要擴展所以引入 Load Balancer,讀取太慢所以引入 Caching,單體架構難以維護所以引入微服務。理解這個「為什麼需要它」的脈絡,比單純記住每個技術是什麼更重要。

不過這部影片畢竟是高層次概覽,每個概念只做了簡要介紹。建議把它當作學習路線圖,針對自己不熟悉的概念再深入研究。特別是 CAP Theorem、Sharding 策略選擇、快取失效策略這些主題,在實際工程中的決策遠比影片中描述的複雜。

進階測驗:系統設計 30 個核心概念

測驗目標:驗證你是否能在實際情境中應用系統設計的核心概念。
共 5 題,包含情境題與錯誤診斷題。

1. 你的電商平台目前使用單一 SQL 資料庫,讀取流量是寫入的 10 倍,資料庫伺服器 CPU 經常飆到 90% 以上。你希望在不改變現有架構太多的情況下改善效能。應該優先採取哪個方案? 情境題

現況: – 單一 PostgreSQL 資料庫 – 讀寫比例約 10:1 – CPU 使用率持續偏高 – 資料量約 50GB,尚未達到單機儲存上限
  • A. 將資料庫進行 Sharding,按 User ID 分片到多台伺服器
  • B. 建立 Read Replica,將讀取查詢分散到多個副本
  • C. 將整個資料庫從 SQL 遷移到 NoSQL 以提升效能
  • D. 對所有資料表的所有欄位建立索引

2. 你正在設計一個即時股票行情看板,需要伺服器在股價變動時主動將最新價格推送給所有連線中的客戶端。以下哪種通訊方式最適合? 情境題

需求: – 伺服器需主動推送資料給客戶端 – 客戶端也需要能即時送出交易請求 – 延遲要求:毫秒級 – 同時連線用戶數:數千人
  • A. 使用 REST API 搭配客戶端每秒輪詢(Polling)
  • B. 使用 Webhook 讓伺服器通知客戶端
  • C. 使用 WebSocket 建立持久雙向連線
  • D. 使用 GraphQL Subscription 搭配 HTTP 長輪詢

3. 你的微服務架構中,訂單服務處理完訂單後需要通知庫存服務扣減庫存、通知郵件服務發送確認信。但郵件服務偶爾會因第三方 API 逾時而回應緩慢。你應該如何設計服務間的通訊? 情境題

現有架構: – 訂單服務(Order Service) – 庫存服務(Inventory Service) – 郵件服務(Email Service) 問題:郵件服務的延遲拖慢了整個訂單流程
  • A. 讓訂單服務直接呼叫庫存和郵件服務的 REST API,並設定較長的逾時時間
  • B. 使用 Message Queue,訂單服務將事件放入佇列,庫存和郵件服務各自消費處理
  • C. 將庫存和郵件功能合併回訂單服務,減少網路呼叫
  • D. 使用 WebSocket 讓訂單服務與郵件服務保持持久連線

4. 團隊為了加速查詢,在用戶表格的每個欄位都建立了索引。上線後發現寫入效能反而大幅下降,新用戶註冊的回應時間從 50ms 增加到 500ms。最可能的原因是什麼? 錯誤診斷

— 用戶表建立了以下索引 CREATE INDEX idx_user_name ON users(name); CREATE INDEX idx_user_email ON users(email); CREATE INDEX idx_user_phone ON users(phone); CREATE INDEX idx_user_address ON users(address); CREATE INDEX idx_user_bio ON users(bio); CREATE INDEX idx_user_created ON users(created_at); CREATE INDEX idx_user_updated ON users(updated_at); — … 對每個欄位都建了索引 — 註冊新用戶時(INSERT 操作)回應時間從 50ms → 500ms
  • A. 每次寫入資料時,所有索引都需要同步更新,過多索引嚴重拖慢寫入速度
  • B. 索引佔用了太多磁碟空間,導致資料庫儲存不足
  • C. 索引語法有誤,資料庫在每次寫入時嘗試修復損壞的索引
  • D. 建立索引後資料庫自動啟用了嚴格模式,導致額外的資料驗證

5. 你的線上支付系統沒有實作冪等性(Idempotency),使用者在付款時因網路不穩定,瀏覽器自動重試了請求。結果使用者被扣款兩次。以下哪個修正方案能正確解決這個問題? 錯誤診斷

問題重現: 1. 使用者點擊「付款」按鈕 2. 請求送出,但網路逾時,客戶端未收到回應 3. 客戶端自動重試相同的付款請求 4. 伺服器將兩次請求都當作新的付款處理 5. 使用者被扣款兩次($100 × 2 = $200)
  • A. 在前端禁用「付款」按鈕,防止使用者重複點擊
  • B. 增加 Rate Limiting,限制每個使用者每分鐘只能發送一次付款請求
  • C. 為每筆付款請求產生唯一的 Idempotency Key,伺服器處理前先檢查該 Key 是否已處理過
  • D. 使用 WebSocket 取代 HTTP,確保伺服器能即時回應避免重試
0

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *