測驗:電腦架構全景圖 — 從硬體到生產環境
共 5 題,點選答案後會立即顯示結果
1. 在電腦的四層儲存中,哪個元件的特性是「速度快,但斷電後資料會消失」?
2. 「水平擴展 (Horizontal Scaling)」指的是什麼?
3. 在 CI/CD 流程中,CI (Continuous Integration) 的主要功能是什麼?
4. 文章提到的 Cache-Aside 模式,其運作流程是什麼?
5. 當 RAM 用完時,系統會採取什麼措施?這會造成什麼影響?
**系列**:系統設計白話文(第 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 → 整個系統要掛了(「資料庫連不上」)
必看懂:INFO 和 ERROR 最常用。看到 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 倍。根據文章所學,最有效的第一步改善措施是什麼? 情境題
2. 你用 AI 寫了一個 Web App,目前只跑在一台伺服器上。老闆說下個月要上電視廣告,預期流量會暴增 10 倍。你需要準備什麼架構改動? 情境題
3. 你的團隊有 3 位開發者,大家都在同一個專案上工作。目前的部署方式是:有人改完程式碼後,手動 SSH 連到伺服器把檔案複製上去。上週有人部署了一個有 bug 的版本,導致網站掛了 2 小時才被發現。根據文章所學,最該優先建立的是什麼? 情境題
4. 小華的 Web App 上線後,使用者抱怨「每次重新登入後,之前加入購物車的商品都不見了」。查看程式碼後發現購物車是這樣實作的: 錯誤診斷
根據文章所學,最可能的原因是什麼?
5. 你的網站突然變很慢,查看監控儀表板後看到以下數據: 錯誤診斷
根據文章所學,最可能的原因是什麼?