這系列文章想陪大家一起做一件事:從零開始設計一個名為 PokeThreads 的社群平台(參考自 Meta 的 Threads),並且讓它隨著使用者變多、流量變大,一步一步演化成真正的分散式系統。
整個系列會從一台 Server、一顆 Database 的陽春版本開始,隨著使用者與流量增加,逐步長成一個具備完整功能的社群平台。內容大致分成三塊:
最後一篇則會整理回顧,把 PokeThreads 從第一版走到今天的演化過程重新看一次。
在正式開始之前,先簡單自我介紹一下,也說說這系列文章想用什麼方式跟大家分享。
我原本是專注於網頁前端的軟體工程師,寫過不少介面與使用者體驗的細節。這幾年我開始花更多時間研究系統的架構面,從前端出發慢慢往後端與資安延伸,試著建立「看懂一個系統」的完整視角。
這系列文章,就是我把學習筆記整理下來,也逼自己重新梳理一次的方式,想呈現的是和讀者一起學習的過程,而不是單方面的教學,裡面難免會有想得不夠周全、甚至寫錯的地方。如果你發現任何錯誤,或是有不同的想法與做法,非常歡迎留言指正、一起討論。
這系列文章也會同步更新到我的個人部落格,之後若內容有修改或補充,會盡量以部落格上的版本為準。
在動手畫任何架構圖之前,先聊聊 System Design(系統設計)到底在討論什麼。
過去軟體工程師的工作,有很大一部分是在把需求轉換成可以運作的程式碼,所以一個工程師的能力,經常會透過 Programming、Code Quality 和 Debugging 等等面向來綜合評估。
近年 AI 程式開發工具逐漸成熟,例如 Cursor、Claude Code、Codex 等工具,可以協助工程師產生、修改、重構與理解程式碼。
Anthropic 的 CEO Dario Amodei 更公開表示:
「內部頂尖工程師已不再手動敲鍵盤寫程式,多數程式碼改由 AI Agent 生成,工程師則轉為負責審查、系統架構與產品決策」。
這不代表寫 Code 已經不重要,只是當「產生程式碼」的成本逐漸降低之後,「我們要讓 AI 寫什麼?」就變得更加重要。
如果需求本身沒有定義清楚,架構沒有設計好或是 Database 選擇錯誤,那麼 AI 可能很快地幫我們產生大量錯誤的程式碼,事後還是要由我們「人類工程師」來擦屁股。
因此,我認為在 AI 輔助開發的時代,工程師更需要具備根據需求做出合理架構的能力,而這正是 System Design 所關注的事情。
System Design 討論的核心問題是:
一個軟體系統要怎麼被拆分、串接與部署,才能滿足現在的需求,並且在使用者與流量成長之後仍然撐得住?
寫程式解決的是「這個功能怎麼做出來」,而 System Design 解決的是更上層的問題:
這些問題沒辦法單靠寫更多 Code 解決,而是要在動手之前,就得先想清楚架構要長什麼樣子。
如果有人丟給你一句話:
「幫我設計一個像 Threads 的東西。」
很容易出現的反應是立刻在白板上畫出 Server、Database、Load Balancer、Cache…… 一口氣把心目中「大型系統該有的樣子」都畫出來。
但這樣做其實跳過了最關鍵的一步:我們都還不知道要解決什麼問題,就已經開始回答了。
「做一個像 Threads 的東西」是一句非常粗略的需求,拿給 10 個工程師,可能會做出 10 種完全不同規模、不同取捨的系統。所以動手之前,應該先把問題問清楚。
先搞懂系統要服務的對象:
以 PokeThreads 來說,我們大致可以先假設使用者會做這幾件事:
接著要定出範疇(Scope),同一句「做一個 Threads」,其實藏著很多可以自由心證的地方:
範疇沒有定義清楚,架構就無從談起,因為「一個能撐住 100 人」和「一個能撐住 1000 萬人」的系統,長相會完全不同。
實務上很常遇到的狀況是:PM 或主管只丟出一句「我們要做一個類似 Threads 的社群功能」,卻答不出每月會有多少活躍用戶,也沒想過資料要一致還是要快。
這時候工程師要做的就是通靈,其實是自己先建立合理的假設,然後拿去跟需求方對過,確認方向沒有偏掉。
把釐清出來的需求,可以分成兩種:
簡單來說,功能性需求決定系統「能不能動」,非功能性需求則決定系統「動得好不好」。
兩者都要考慮,但初期通常會先把心力放在功能性需求上,非功能性需求則隨著規模成長逐步補上,這也是這個系列主要會採取的敘事方式。
需求確認之後才輪到畫架構,但要先建立一個心態:System Design 沒有一個放諸四海皆準的正確答案。
Netflix 跟 YouTube 表面上都是「讓人看影片的服務」,但一個重點在串流授權內容、一個重點在使用者上傳的海量內容,兩者的架構取捨完全不同。同理,一個 100 人在用的社群工具,跟一個 10 億人在用的社群平台,也不會套用同一套架構。
所以與其追求「最好的架構」,不如把目標放在:在現在的限制條件下,做出最合理的取捨(Trade-off)。
需求確定之後,動手畫架構之前,還有一步很容易被忽略:粗估這個系統大概要處理多少流量、多少資料量。
核心換算邏輯是:
Users -> User Actions -> Requests -> QPS / Storage / Bandwidth
把「有多少使用者」,換算成

這一步不追求精準,重點是抓對「數量級」,這種算法有個名字叫 Back-of-the-envelope calculation,意思是拿張隨手可得的紙,用簡化過的數字快速估算。習慣上也會把數字四捨五入到方便計算的整數,例如 97 約等於 100、365 天約等於 400 天。
假設我們現在訂出幾個假設:
每日寫入 = 1000萬 × 1% = 10萬篇 / 天
每秒寫入 = 10萬 / 86400 ≈ 10萬 / 8萬6 ≈ 1~2 QPS
每日讀取 = 10萬 × 100 = 1000萬次 / 天
每秒讀取 = 1000萬 / 8萬6 ≈ 100 QPS
每天新增資料 = 10萬篇 × 1KB = 100MB
5 年資料量 ≈ 100MB × 365 × 5 ≈ 200GB
如果再考慮多副本備份(例如 3 份),大概就要準備 600GB 上下的容量。
寫入頻寬 = 1~2 QPS × 1KB ≈ 每秒 1KB
讀取頻寬 = 100 QPS × 1KB ≈ 每秒 100KB 左右
算完之後會發現,這種規模其實一台普通的 Server 加一顆 Database 就綽綽有餘,這正是下一篇要從最簡單版本開始的原因——先確認需求真的到什麼程度,再決定要蓋多大的系統,而不是還沒算過帳,就先把 Cache、Message Queue、多台 Server 全部搬上架構圖。
回到前面「AI 時代,System Design 變得更重要」那段留下的問題:從釐清需求、抓 Trade-off,到剛剛這一整套 Capacity Estimation,有沒有可能乾脆都交給 AI 來做?有人覺得 System Design 是人類最後的護城河,但這是真的嗎?這個問題我覺得值得拆成兩半來看。
當需求已經定義得很清楚,就像我們剛剛幫 PokeThreads 算出來的「1000 萬 DAU、Read/Write 比 100:1」,從這種清楚的需求推導出合理架構,其實已經有大量公開資料可以參考,包括 System Design 面試題、各家公司的 Engineering Blog、開源架構文件,這些都可能是 AI 訓練資料的一部分。
對於這種「已經定義清楚、有大量前例可循」的標準情境,AI 給出的架構建議很可能已經不輸一般工程師,未來甚至可能更快、更全面。
實務上的 System Design,最花時間的往往不是「畫出架構圖」或「算數字」,而是前面釐清需求那段提到的過程:
面對 PM 只丟一句「做一個類似 Threads 的東西」,得自己去猜、去問、去跟不同角色的人反覆確認範疇與限制。
這些限制常常不是純技術問題,而是牽涉到團隊現有的技術棧、預算、時程,甚至公司內部的政治角力,整體脈絡沒有寫在任何文件裡,AI 也就無從得知,有時連人類都得自己揣摩上意😂。
另外,架構決策的回饋週期很長,一個 Trade-off 選得好不好,往往要等系統真的跑上好幾個月甚至好幾年、遇到瓶頸才會知道,而做出這個決策並為結果負責的,終究還是人。
所以我自己的看法是:AI 會愈來愈擅長「給定清楚需求,產生合理架構」這件事,但「把模糊的人類需求,轉換成清楚的問題」這一步,短期內還是得靠人。
這也正好是這系列文章想練習的能力,與其說是在學怎麼畫架構圖,不如說是在練習怎麼把問題問清楚、怎麼做出合理的取捨。
今天完全沒有畫任何架構圖,因為 System Design 的第一步,本來就不是架構圖,而是先把問題問清楚:
釐清使用者與情境
↓
定義 Functional / Non-Functional Requirements
↓
確認 Scope 與限制
↓
Capacity Estimation
↓
才開始 Architecture Design
有了流量與資料量的量級,才知道現在的系統到底需不需要 Load Balancer、需不需要 Cache、需不需要拆分 Database——這些答案,都要等到把「數字」算出來之後才有意義。
下一篇開始,我們就會依照今天估算出的規模,動手做出第一版最陽春的 PokeThreads。