假設一個網站只有一台資料庫。
使用者註冊、登入、修改資料、查詢文章,所有操作都送到同一台機器。規模還小時,這通常沒有問題;甚至是最簡單、最好維護的架構。
但當服務逐漸變大,兩個問題會開始出現。
第一個是效能:如果同時有大量使用者查詢資料,一台資料庫可能開始忙不過來。
第二個是可靠性:如果這唯一的一台資料庫故障,整個服務可能瞬間失去讀寫能力。
於是工程師會開始思考:能不能讓同一份資料存在不只一台資料庫?
這就是 Database Replication(資料庫複寫)要處理的核心問題。
Replication 不是單純「複製檔案」
直覺上,你可能會把 Replication 想成定期把 database.db 複製一份到另一台電腦。
但真正的資料庫系統通常不是這樣運作。
資料庫持續接受 INSERT、UPDATE、DELETE 等操作,資料每秒都可能改變。如果只是偶爾複製整個檔案,副本很快就會落後,而且複製過程還可能遇到資料正在變動的問題。
因此,Replication 通常會追蹤資料庫發生的變更,再把這些變更傳給其他節點。
概念上可以想成:
Primary Database
產生資料變更
Replication Stream / Log
Replica Database
Primary 寫入一筆新資料後,Replica 接收到相同的變更,最後讓兩邊保持接近一致。
不同資料庫的實作細節不同。例如 PostgreSQL 可以透過 WAL(Write-Ahead Log)進行複寫,MySQL 則常利用 binary log 傳遞變更。但核心概念相同:不是每次重新複製整個資料庫,而是持續傳遞「發生了什麼改變」。
Primary 與 Replica
最常見的架構之一是 Primary–Replica。
Primary 是主要資料庫,負責接受寫入:
INSERT
UPDATE
DELETE
Replica 則持續接收 Primary 的資料變更,建立自己的副本。
例如:
Replication
↙ ↘
Replica A Replica B
這樣做有一個很重要的用途:讀取可以分散出去。
如果網站有大量「讀」操作,例如新聞網站、文章平台或商品頁面,很多請求只是 SELECT,並不會修改資料。這些查詢不一定全部都要打到 Primary。
因此架構可能變成:
這類 Replica 常被稱為 Read Replica。
Read Replica 為什麼能減輕壓力?
假設一秒有 10,000 個資料庫操作,其中只有 500 個是寫入,另外 9,500 個都是讀取。
如果所有操作都送到 Primary,它必須獨自處理全部工作。
但如果加入多個 Read Replica,應用程式可以把大量 SELECT 分散到其他節點。Primary 主要處理需要一致性的寫入,而 Replica 幫忙承擔讀取流量。
這就是常見的 Read Scaling。
不過這並不是免費的效能提升。
因為只要資料需要從 Primary 傳到 Replica,就一定會出現一個重要問題:Replica 到底多久才會追上 Primary?
Replication Lag:副本可能慢半拍
假設使用者剛修改自己的暱稱:
應用程式把 UPDATE 送到 Primary,Primary 成功寫入。
但 Replica 可能還沒收到這次更新。
如果下一個畫面剛好從 Replica 查詢資料,就可能短暫看到舊暱稱。
這段「Primary 已經更新,但 Replica 還沒追上」的差距,就是 Replication Lag。
它可能只有幾毫秒,也可能因網路、負載或 Replica 故障而變成數秒甚至更久。
因此使用 Replica 時,工程師不能只問「查詢能不能分流」,還要問:「這筆資料允許看到稍微舊一點的版本嗎?」
像文章瀏覽數、推薦內容或公開資訊,短暫延遲通常可以接受。
但剛完成付款、修改權限、重設密碼等操作,就可能不能接受讀到舊資料。
這也是分散式系統中 Consistency 問題開始出現的地方。
同步複寫與非同步複寫
Replication 大致可以分成同步(Synchronous)與非同步(Asynchronous)兩種思路。
### 非同步複寫
Primary 完成寫入後,不必等待 Replica 確認,就可以先告訴應用程式「成功」。
流程類似:
優點是寫入延遲較低,Primary 不需要每次等待遠端節點。
缺點是,如果 Primary 在資料尚未送到 Replica 前突然故障,最新的一小段資料可能還不存在於副本。
### 同步複寫
同步複寫則要求某些 Replica 先確認收到或寫入資料,Primary 才把操作視為成功。
流程更接近:
這可以降低 Primary 突然故障時遺失最新資料的風險,但代價是寫入必須等待更多網路與磁碟操作,因此 latency 通常會增加。
所以同步與非同步並不是「哪個比較高級」,而是 Durability、Consistency、Latency 與可用性之間的取捨。
Failover:Primary 掛掉之後怎麼辦?
Replication 的另一個重要用途是 High Availability(高可用性)。
假設 Primary 突然故障:
Primary ✕
Replica A ✓
Replica B ✓
如果 Replica 已經保有足夠完整的資料,系統可以選出其中一台,把它提升成新的 Primary。
這個過程叫做 Failover。
概念上是:
原本:
故障後:
應用程式接著把寫入流量導向新的 Primary。
有些系統需要人工操作,有些雲端資料庫或叢集管理系統可以自動偵測故障並執行 Failover。
但「自動 Failover」其實很難。
系統必須確認原本的 Primary 真的失效,而不是只是暫時網路不通。如果判斷錯誤,可能出現兩台節點都以為自己是 Primary 的情況,這類問題常被稱為 Split Brain。
因此高可用架構不是單純多放幾台資料庫,而是還需要健康檢查、節點選舉、流量切換與一致性控制。
Replica 越多越好嗎?
不一定。
增加 Replica 可以提供更多讀取能力,也可能提高故障時的選擇空間,但同時會增加:
複寫流量
監控成本
節點管理成本
延遲與一致性問題
故障排查複雜度
而且 Replica 本身也需要 CPU、RAM、儲存空間與網路。
對一個每天只有幾十個使用者的小網站來說,一台可靠的資料庫加上完整備份,往往比建立複雜的多節點架構更合理。
架構設計不是「元件越多越專業」,而是讓複雜度與實際需求相符。
Replication 不等於 Backup
這是最容易混淆、也最重要的一點之一。
你有三台 Replica,不代表你就有三份安全的備份。
假設有人誤執行:
DELETE FROM users;
Primary 忠實地刪除了 users 資料。
Replication 系統接下來做什麼?
它很可能也會忠實地把 DELETE 傳到所有 Replica。
幾秒後:
Primary:資料被刪掉
Replica A:資料被刪掉
Replica B:資料被刪掉
Replication 的目標是「讓副本跟著現在的資料狀態」,而 Backup 的目標則是「讓你可以回到過去某個狀態」。
因此真正重要的系統通常同時需要:
Replication:處理可用性、讀取擴展與節點故障。
Backup:處理誤刪、資料毀損、勒索軟體或需要回復歷史版本的情況。
兩者解決的是不同問題。
Replication 也不是 Sharding
另一個常見混淆是 Sharding。
Replication 是把同一份資料複製到多個節點。
例如:
DB A:Users 1–1,000,000
DB B:Users 1–1,000,000
兩邊都有相同資料。
Sharding 則是把不同資料拆到不同節點:
Shard A:Users 1–500,000
Shard B:Users 500,001–1,000,000
因此兩者的目標不同。
Replication 常用來提高可用性與讀取能力;Sharding 則是在單一資料庫已經難以容納或處理全部資料時,把資料水平切分。
大型系統甚至可能同時使用兩者:先把資料切成多個 Shard,每個 Shard 再各自建立 Replica。
一個完整的請求可能怎麼走?
假設某個網站使用一台 Primary 加兩台 Replica。
使用者新增文章時:
Browser
API Server
Primary Database
寫入成功
Replication Log
Replica A / Replica B
而另一名使用者讀取文章列表時:
Browser
API Server
Read Replica
回傳文章
這樣 Primary 不需要處理所有讀取流量。
但如果第一位使用者新增文章後立刻重新整理,系統可能刻意讓這次查詢仍然讀 Primary,確保他馬上看到剛才建立的資料。這種設計常被稱為 Read-after-write consistency 的處理方式之一。
所以「讀寫分離」真正落地時,並不是簡單地把 SELECT 全部丟給 Replica,而是要知道哪些查詢可以接受 eventual consistency,哪些不能。
怎麼知道 Replication 正常?
建立複寫之後,監控非常重要。
常見觀察項目包括:
Replica 是否在線
Replication Lag 有多大
最後成功同步的時間
Primary 與 Replica 的 WAL / log 位置差距
Replica 的 CPU、磁碟與網路負載
Failover 是否真的能成功
如果只看到「Replica Running」就認為一切正常,可能會漏掉一個很危險的狀況:Replica 雖然活著,但已經落後幾小時。
真正的可靠性需要可以量測。
什麼時候才需要 Replication?
如果你正在做個人專案,不必看到大型網站的架構就立刻照抄。
可以先問四個問題:
第一,單一資料庫故障時,我能接受服務停止多久?
第二,讀取流量是否真的已經成為瓶頸?
第三,我的應用能不能接受部分查詢讀到稍微舊的資料?
第四,我是否有能力監控、維護並測試 Failover?
如果這些問題都還沒有形成實際需求,那麼把一台資料庫做好、建立自動備份、測試 Restore,通常比直接增加 Replica 更有價值。
最後整理
Database Replication 的核心並不複雜:讓資料的變更從主要資料庫持續傳到其他資料庫節點,使系統擁有多份接近一致的資料副本。
它可以用來分散讀取、提高可用性,並在 Primary 故障時提供 Failover 的基礎。但副本可能存在 Replication Lag;同步與非同步複寫也會在一致性、延遲與耐久性之間做不同取捨。
最重要的是記住三個區別:
Replication 不是 Backup。
Replication 不是 Sharding。
有 Replica 也不代表系統自動變成高可用。
真正可靠的資料庫架構,除了「多一份資料」,還需要監控、故障切換、備份與復原策略一起存在。
當你理解這一點,再看到 Primary、Read Replica、Failover、Replication Lag 這些詞,它們就不再只是雲端平台上的設定選項,而是一整套在效能、可用性與一致性之間做取捨的設計方法。
把概念放回真正的系統流程裡看,通常比只背名詞更容易理解它。