iT邦幫忙

2026 iThome 鐵人賽

DAY 27
0
Software Development

文科生的軟體工程啟蒙:用一個代購 App,看懂 30 個系統設計觀念系列 第 27 篇

Day 27:規模化考量(Scalability)——當資料量增加 100 倍時,架構該如何演進?

  • 分享至 

  • xImage
  •  

前面談過的快取(Day 10)、原子操作(Day 11)、正規化資料(Day 6、23),都是在資料量還不算太大的前提下討論的。今天要把視角拉遠:如果代購 App 真的成功,使用者和訂單量成長了 100 倍,這些既有的設計該怎麼跟著演進。

一、垂直擴展 vs. 水平擴展

垂直擴展(Scale Up):把單一伺服器的規格加大——更多 CPU、更多記憶體。做法簡單,但終究會碰到硬體規格的物理上限,而且單一伺服器掛掉時,整個系統就會停擺。

水平擴展(Scale Out):增加更多台伺服器一起分攤負載,而不是依賴一台更強的機器。理論上沒有硬性的規模上限,單一機器故障時,其他機器仍能繼續運作,但需要處理「資料該怎麼分散在多台機器上」這個新問題。

二、資料庫層面:索引、複製、分片

索引(Index):資料表還小的時候,就算沒有索引,全表掃描也感覺不出差異;但資料量一大,沒有索引的查詢就會呈現 Day 23 談過的線性成長,變得越來越慢。

複製(Replication):把資料庫整份複製到多台伺服器,讓讀取的請求可以分散到不同的複本上,提升讀取吞吐量與系統可用性,但無法解決單一資料表本身過大、或寫入量過高的問題。

分片(Sharding):把一張巨大的資料表,依照某個規則(例如買家 ID)拆分到多台資料庫伺服器上,每台伺服器只負責其中一部分資料。這是真正解決「資料量本身太大、單台機器裝不下」問題的做法,但也讓查詢邏輯變得更複雜(例如跨分片的查詢)。

三、應用層面:快取與非同步佇列

資料量一大,Day 10 談過的快取策略變得更重要——把常被查詢、不常變動的資料(例如商品分類)放進 Redis 這類快取層,減少每次都要打資料庫的壓力。而 Day 11 談過的原子操作,在高併發的場景下也往往不夠:當瞬間湧入大量訂單請求時,直接讓每個請求都同步搶著更新同一張庫存資料表,資料庫很容易撐不住,這時候通常會把「扣庫存、建訂單」這類寫入操作,改成丟進一個訊息佇列(Message Queue),由後端依序、非同步地消化,而不是要求資料庫立刻同步處理每一筆請求。

四、代購 App 案例

當訂單資料表從幾千筆成長到几百萬筆:原本沒有索引的 buyer_id 查詢,速度會明顯下降,第一步通常是先補上索引;當讀取流量(買家查詢自己的訂單)遠大於寫入流量時,加入 Read Replica 分攤查詢壓力,搭配 Day 10 的快取策略,把熱門商品資訂快取起來;當某次促銷活動湧入大量下單請求時,不再讓每筆請求直接同步寫入資料庫,而是先把訂單請求放進佇列,由背景服務依序處理,搭配 Day 11 的原子操作確保庫存不會被搶超。

五、結論

規模化不是一次性的架構重建,而是隨著資料量與流量的成長,逐步把「單一伺服器、同步處理」的簡單假設,替換成「多台伺服器分攤、非同步處理」的設計。這些調整大多不是全新的概念,而是把前面幾天談過的索引、快取、原子操作,應用在更大的規模下,並補上分片、佇列這類新的工具來因應資料量帶來的新限制。


上一篇
Day 26:程式碼品質工具鏈——Linter、Formatter 與 Git Hooks 的自動化約束
下一篇
Day 28:AI 時代的架構師思維——當程式碼能自動生成,人類工程師的核心價值在哪?
系列文
文科生的軟體工程啟蒙:用一個代購 App,看懂 30 個系統設計觀念 共 29 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言