【系統設計白話文】#01 電腦架構全景圖 — 從硬體到生產環境

測驗:電腦架構全景圖 — 從硬體到生產環境

共 5 題,點選答案後會立即顯示結果

1. 在電腦的四層儲存中,哪個元件的特性是「速度快,但斷電後資料會消失」?

  • A. 磁碟 (Disk)
  • B. RAM 記憶體
  • C. CPU
  • D. 負載均衡器

2. 「水平擴展 (Horizontal Scaling)」指的是什麼?

  • A. 把一台伺服器的 CPU 換成更快的
  • B. 增加單台伺服器的 RAM 容量
  • C. 多加幾台電腦來分擔工作
  • D. 把磁碟升級成更大容量的 SSD

3. 在 CI/CD 流程中,CI (Continuous Integration) 的主要功能是什麼?

  • A. 自動將程式碼部署到所有伺服器
  • B. 每次推程式碼時自動跑測試確認沒壞
  • C. 即時監控伺服器的 CPU 使用率
  • D. 管理負載均衡器的流量分配

4. 文章提到的 Cache-Aside 模式,其運作流程是什麼?

  • A. 先查快取,沒有就查資料庫,查到後順便存進快取
  • B. 同時查快取和資料庫,哪個先回就用哪個
  • C. 先寫入快取,再同步寫入資料庫
  • D. 先查資料庫,查到後存進快取,下次直接從快取讀

5. 當 RAM 用完時,系統會採取什麼措施?這會造成什麼影響?

  • A. 系統會自動清除不常用的資料,效能不受影響
  • B. 系統會停止接受新的請求,直到有 RAM 被釋放
  • C. 系統會用磁碟假裝 RAM(swap),速度慢約 1000 倍
  • D. 系統會自動啟動更多伺服器來分擔記憶體壓力

**系列**:系統設計白話文(第 1 篇,共 5 篇)
**難度**:L2-進階
**前置知識**:無(從零開始)
**影片來源**:freeCodeCamp “System Design Concepts Course and Interview Prep” by Hayk Simonyan

一句話說明

電腦靠四層儲存跑程式,生產環境靠多台電腦 + 一堆自動化工具撐住真實流量。


為什麼 Vibe Coder 要懂這個?

你用 AI 寫了一個 Web App,本機跑得好好的。結果一部署到雲端,要嘛慢得要命、要嘛直接掛掉。為什麼?

因為你不知道:

  • 你的資料存在哪裡(磁碟?記憶體?快取?)
  • 一台伺服器能撐多少人
  • 東西壞了怎麼知道壞在哪

這篇用最白話的方式,帶你從「一台電腦裡面長什麼樣」一路看到「一個真正的生產環境長什麼樣」。


第一章:電腦裡面的四層儲存

想像你在做菜。你需要一個地方放食材、一個地方備料、手邊要有正在處理的東西,腦子裡要記住食譜步驟。

電腦也一樣,有四個「放東西的地方」,速度和容量差很多:

┌─────────────────────────────────────────────────┐
│                    CPU(大腦)                    │
│              負責執行運算,速度最快                │
│         ┌───────────────────────┐                │
│         │    快取 Cache(口袋)  │                │
│         │   奈秒等級,超小超快   │                │
│         └───────────────────────┘                │
└─────────────────────────────────────────────────┘
                      ↑ 越上面越快,但容量越小
                      │
┌─────────────────────────────────────────────────┐
│              RAM 記憶體(工作桌)                  │
│          微秒等級,幾 GB ~ 幾十 GB               │
│          電源關掉資料就消失(揮發性)              │
└─────────────────────────────────────────────────┘
                      │
┌─────────────────────────────────────────────────┐
│              磁碟 Disk(倉庫)                    │
│          毫秒等級,幾百 GB ~ 幾 TB               │
│          電源關掉資料還在(持久性)                │
└─────────────────────────────────────────────────┘

白話翻譯:各元件是幹嘛的

元件 比喻 速度 容量 斷電後
磁碟 (Disk) 倉庫 最慢(毫秒) 最大(TB 級) 資料還在
RAM 記憶體 工作桌 快(微秒) 中等(GB 級) 資料消失
快取 (Cache) 口袋 超快(奈秒) 超小(MB 級) 資料消失
CPU 大腦 最快 不存資料

速度差多少?用實際感受來比

這些速度差距不是「快一點點」,是天差地別:

磁碟讀取一次 ≈ 幾毫秒 (ms)      → 眨一下眼
RAM 讀取一次  ≈ 幾百奈秒 (ns)     → 想都不用想
快取讀取一次  ≈ 幾奈秒 (ns)       → 比想都不用想還快 100 倍

1 毫秒 = 1,000 微秒 = 1,000,000 奈秒

關鍵數字:磁碟比 RAM 慢大約 1,000 到 100,000 倍。這就是為什麼把常用資料從磁碟搬到記憶體,效能會有天壤之別。

Vibe Coder 什麼時候會碰到這個?

當你看到 AI 幫你寫的程式碼出現這些東西時,它就在跟這四層儲存打交道:

# 讀磁碟 — 最慢,但資料不會消失
with open("data.json") as f:     # 從磁碟讀檔案
    data = json.load(f)          # 把檔案內容載入記憶體

# 用 RAM — 快,但程式關掉就沒了
cache = {}                        # 在記憶體建一個字典
cache["user_123"] = user_data     # 把資料存在記憶體裡

# 用 Redis(外部快取服務)— 獨立的快取伺服器
redis.set("user_123", user_data)  # 存到 Redis 快取
redis.get("user_123")             # 從 Redis 讀取,比讀資料庫快很多
Code language: PHP (php)

翻譯

  • open("data.json") → 去倉庫(磁碟)拿東西,慢
  • cache = {} → 在工作桌(RAM)上放東西,快但重開就沒了
  • redis.set(...) → 用專門的快取服務,介於磁碟和程式記憶體之間

第二章:為什麼這對系統設計很重要?

理解儲存階層後,很多系統設計的決策就變得直覺了:

決策 1:要不要加快取?

使用者請求 → 先查快取 → 有就直接回(快)
                ↓ 沒有
            查資料庫 → 回傳 + 順便存進快取(下次就快了)

這個模式叫做 Cache-Aside,你會在各種系統設計裡看到它。白話翻譯就是:「先翻口袋,口袋沒有再去倉庫拿,拿完順手放口袋。」

決策 2:資料庫選擇

需要持久保存的資料(用戶資料、訂單)→ 存磁碟(資料庫)
需要快速存取的暫時資料(登入狀態)  → 存記憶體(Redis)

決策 3:為什麼程式「吃記憶體」是個問題?

RAM 滿了 → 系統開始用磁碟假裝 RAM(swap)
        → 速度從微秒變毫秒
        → 慢 1000 倍
        → 使用者覺得網站掛了

第三章:從一台電腦到生產環境

好,你已經懂一台電腦裡面的構造了。但真正的生產環境不是「一台電腦」,而是一整套系統。

一個請求的完整旅程

當使用者打開你的網站,背後發生了什麼?

使用者瀏覽器
    │
    ▼
┌──────────────┐
│  負載均衡器    │  ← 交通警察,決定請求送去哪台伺服器
│ Load Balancer │
└──────┬───────┘
       │
   ┌───┼───┐
   ▼   ▼   ▼
┌────┐┌────┐┌────┐
│ S1 ││ S2 ││ S3 │  ← 三台一模一樣的伺服器,跑同樣的程式
└────┘└────┘└────┘
   │   │   │
   └───┼───┘
       ▼
┌──────────────┐
│   資料庫       │  ← 所有伺服器共用同一個資料庫
│  Database     │
└──────────────┘

白話翻譯

元件 比喻 做什麼
負載均衡器 餐廳帶位員 把客人(請求)分配給不同服務生(伺服器)
伺服器群 多個服務生 每個都能處理請求,一個忙就換另一個
資料庫 廚房 所有服務生共用同一個廚房(資料來源)

為什麼需要多台伺服器?

單台伺服器的極限:
- CPU 100% → 算不動了
- RAM 用完 → 慢到爆
- 網路頻寬滿了 → 請求排隊等
- 伺服器掛了 → 整個網站掛了(單點故障)

解法:水平擴展(加更多台)
- 3 台伺服器各分擔 1/3 流量
- 1 台掛了,其他 2 台繼續撐
- 流量變大?再加幾台就好

這就是所謂的 水平擴展 (Horizontal Scaling):不是把一台電腦變更強(垂直擴展),而是多加幾台電腦來分擔工作。


第四章:程式碼怎麼上到伺服器?— CI/CD

你在本機寫完程式碼,怎麼把它放到那三台伺服器上?總不能一台一台手動部署吧。

CI/CD Pipeline 全景

你的程式碼(本機)
    │
    ▼ git push
┌──────────────────────────────────────┐
│           CI/CD Pipeline             │
│                                      │
│  1. 拉取程式碼                        │
│  2. 安裝依賴                          │
│  3. 跑自動化測試                      │
│  4. 打包(建構 Docker Image 等)      │
│  5. 部署到所有伺服器                  │
└──────────────────────────────────────┘
    │
    ▼ 自動部署
┌────┐┌────┐┌────┐
│ S1 ││ S2 ││ S3 │
└────┘└────┘└────┘

白話翻譯

步驟 在幹嘛
CI (Continuous Integration) 每次推程式碼,自動跑測試確認沒壞
CD (Continuous Deployment) 測試通過後,自動部署到伺服器

Vibe Coder 會看到的 CI/CD 設定

AI 幫你寫的專案裡,常常會有這種檔案:

# .github/workflows/deploy.yml — GitHub Actions 的 CI/CD 設定
name: Deploy           # 這個自動化流程叫什麼名字

on:
  push:
    branches: [main]   # 當有人推程式碼到 main 分支時觸發

jobs:
  deploy:
    runs-on: ubuntu-latest   # 在一台乾淨的 Ubuntu 機器上跑
    steps:
      - uses: actions/checkout@v4   # 第一步:拉取程式碼
      - run: npm install            # 第二步:安裝依賴
      - run: npm test               # 第三步:跑測試
      - run: npm run build          # 第四步:打包
      # 第五步:部署到伺服器(各家雲端不同)
Code language: PHP (php)

翻譯:「只要有人把程式碼推到 main 分支,就自動測試、打包、部署。」


第五章:東西壞了怎麼辦?— 日誌與監控

生產環境最怕的不是「出 bug」,而是「出了 bug 但不知道在哪」。

日誌 (Logging):程式的黑盒子

import logging

logger = logging.getLogger(__name__)

def process_order(order_id):
    logger.info(f"開始處理訂單 {order_id}")      # 記錄「正常事件」
    try:
        result = charge_payment(order_id)
        logger.info(f"訂單 {order_id} 付款成功")  # 記錄「成功」
    except Exception as e:
        logger.error(f"訂單 {order_id} 付款失敗: {e}")  # 記錄「出錯了」
Code language: PHP (php)

翻譯logger.info()logger.error() 就像在程式裡面放錄影機,記錄每一步發生了什麼事。出問題時可以回放找原因。

日誌的層級

DEBUG   → 開發時的細節(通常生產環境不開)
INFO    → 正常運作的記錄(「訂單 123 已建立」)
WARNING → 有點不對但還能跑(「磁碟快滿了」)
ERROR   → 出錯了(「付款失敗」)
CRITICAL → 整個系統要掛了(「資料庫連不上」)

必看懂INFOERROR 最常用。看到 logger.error() 就知道這裡在處理出錯的情況。

監控 (Monitoring):系統的儀表板

日誌是「出事後回去查」,監控是「即時看著」:

監控系統會追蹤:
┌─────────────────────────────────────┐
│  CPU 使用率:  ████████░░ 78%       │  ← 快到 100% 要注意
│  記憶體使用:  ██████░░░░ 62%       │  ← 超過 80% 就危險
│  請求回應時間:平均 120ms            │  ← 突然變大表示有問題
│  錯誤率:     0.1%                  │  ← 突然升高要立刻查
│  每秒請求數:  1,200 req/s          │  ← 流量指標
└─────────────────────────────────────┘

警報 (Alerting)

設定規則:
- 如果錯誤率 > 5% 持續 5 分鐘 → 發 Slack 通知
- 如果 CPU > 90% 持續 10 分鐘 → 發 PagerDuty 告警
- 如果伺服器完全無回應 → 立刻打電話叫人

翻譯:監控 + 警報就像是「請一個人 24 小時盯著儀表板,有異常就喊人」。


第六章:全景圖 — 全部串起來

現在把所有東西組合在一起:

    開發者(你)
        │
        ▼ git push
   ┌─────────────┐
   │   CI/CD      │  ← 自動測試 + 部署
   └──────┬──────┘
          │ 部署完成
          ▼
   ┌──────────────┐
   │  負載均衡器    │  ← 分配流量
   └──────┬───────┘
      ┌───┼───┐
      ▼   ▼   ▼
   ┌────┐┌────┐┌────┐
   │ S1 ││ S2 ││ S3 │  ← 跑你的程式
   └─┬──┘└─┬──┘└─┬──┘
     │     │     │
     └──┬──┘     │
        ▼        ▼
   ┌────────┐ ┌───────┐
   │ 資料庫  │ │ 快取   │  ← 持久儲存 + 快速存取
   │ (磁碟) │ │(Redis)│
   └────────┘ └───────┘
     │     │     │
     ▼     ▼     ▼
   ┌──────────────────┐
   │  日誌與監控系統     │  ← 記錄一切 + 即時警報
   │  Logging/Monitor  │
   └──────────────────┘

每個元件的一句話總結

元件 一句話
CI/CD 推程式碼自動測試部署,不用手動
負載均衡器 把流量平均分給多台伺服器
伺服器群 多台機器跑同樣的程式,互相備援
資料庫 持久存資料,關機重開資料還在
快取 把常用資料放記憶體,加速讀取
日誌 記錄程式每一步做了什麼,出事回查
監控 即時追蹤系統狀態,異常自動警報

Vibe Coder 檢查點

下次看到 AI 幫你生成的專案時,確認以下幾點:

  • [ ] 有沒有 CI/CD 設定檔?(.github/workflows/Jenkinsfile
  • [ ] 資料是存在磁碟還是記憶體?重開之後資料還會在嗎?
  • [ ] 有沒有加日誌?出問題時能不能查到原因?
  • [ ] 如果流量變大,這個架構能加伺服器嗎?還是卡在單機?
  • [ ] 有沒有用到快取?是自己做的記憶體快取還是 Redis 這類外部服務?

必看懂 vs 知道就好

必看懂(這篇的核心概念)

  • 儲存階層:磁碟 → RAM → 快取 → CPU,速度差距是千倍萬倍
  • 水平擴展:多加機器分擔流量,比升級單機更實際
  • CI/CD:自動化測試和部署的流水線
  • 日誌和監控:出問題能查、能即時發現

知道就好(後面幾篇會深入)

  • 負載均衡的具體演算法(Round Robin、Least Connections 等)
  • 資料庫的主從複製、分片策略
  • 快取失效策略(TTL、LRU 等)
  • 容器化部署(Docker、Kubernetes)

本篇重點回顧

1. 一台電腦有四層儲存:磁碟(慢但持久)→ RAM(快但會消失)
   → 快取(更快更小)→ CPU(負責運算)

2. 速度差距是千倍級:所以「資料放哪裡」直接決定系統快不快

3. 生產環境不是一台電腦:而是多台伺服器 + 負載均衡 + 資料庫 + 快取

4. CI/CD 讓部署自動化:推程式碼就自動測試和部署

5. 日誌和監控是生命線:沒有它們,出問題只能瞎猜

**下一篇預告**:【系統設計白話文】#02 — 我們會深入探討系統設計中最核心的取捨與策略。

進階測驗:電腦架構全景圖 — 從硬體到生產環境

測驗目標:驗證你是否能在實際情境中應用所學。
共 5 題,包含情境題與錯誤診斷題。

1. 你的電商網站在促銷活動期間,商品頁面的載入時間從平常的 100ms 暴增到 3 秒。查看監控後發現資料庫的查詢量是平時的 20 倍。根據文章所學,最有效的第一步改善措施是什麼? 情境題

  • A. 把資料庫伺服器的 CPU 和 RAM 升級到最高規格
  • B. 在資料庫前面加一層快取(如 Redis),將熱門商品資料存在記憶體
  • C. 增加更多的負載均衡器來分散流量
  • D. 在每台伺服器的磁碟上建立商品資料的副本

2. 你用 AI 寫了一個 Web App,目前只跑在一台伺服器上。老闆說下個月要上電視廣告,預期流量會暴增 10 倍。你需要準備什麼架構改動? 情境題

  • A. 把伺服器的 RAM 從 16GB 升級到 256GB 就好
  • B. 先把程式碼優化到極致,一台伺服器就能撐住
  • C. 多加幾台伺服器就好,其他不用管
  • D. 加入負載均衡器 + 多台伺服器 + 確保有日誌與監控系統

3. 你的團隊有 3 位開發者,大家都在同一個專案上工作。目前的部署方式是:有人改完程式碼後,手動 SSH 連到伺服器把檔案複製上去。上週有人部署了一個有 bug 的版本,導致網站掛了 2 小時才被發現。根據文章所學,最該優先建立的是什麼? 情境題

  • A. 限制只有一個人可以部署,避免混亂
  • B. 增加更多伺服器,這樣一台壞了其他還能用
  • C. 建立 CI/CD 流程 + 日誌與監控系統
  • D. 把程式碼的快取機制改好,這樣出 bug 影響比較小

4. 小華的 Web App 上線後,使用者抱怨「每次重新登入後,之前加入購物車的商品都不見了」。查看程式碼後發現購物車是這樣實作的: 錯誤診斷

cart = {} # 在記憶體建一個字典 cart[user_id] = item_list # 把購物車資料存在記憶體裡

根據文章所學,最可能的原因是什麼?

  • A. 字典的 key 有誤,user_id 應該轉成字串
  • B. 購物車資料存在 RAM 中,伺服器重啟或程式重開後資料就消失了
  • C. 快取容量太小,資料被自動清除了
  • D. 負載均衡器把使用者導到不同伺服器,另一台沒有這筆資料

5. 你的網站突然變很慢,查看監控儀表板後看到以下數據: 錯誤診斷

CPU 使用率: 32% 記憶體使用: 98% 磁碟使用率: 45% 請求回應時間:平均 4,500ms(平常是 120ms) 錯誤率: 0.3%

根據文章所學,最可能的原因是什麼?

  • A. CPU 不夠力,需要升級處理器
  • B. 磁碟快滿了,需要清理空間
  • C. RAM 幾乎用完,系統可能在使用 swap,導致速度從微秒變毫秒
  • D. 錯誤率偏高,程式有大量未處理的例外

發佈留言

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