SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 已更新 2026-08-13

RAID 10 是什麼?VPS 為何選用 NVMe 儲存

了解 RAID 1、5、6、10 可承受的故障數、重建成本與 NVMe VPS 選用 RAID 10 的原因,並學會查看 /proc/mdstat,以及為何 RAID 不是備份。

RAID 10 的定義,以及 VPS 主機為何採用它

RAID 10 是多數 VPS 主機在虛擬化 NVMe(非揮發性記憶體 express)磁碟上採用的儲存配置。它會將每個磁碟鏡像到另一個配對磁碟,再將資料分條寫入這些鏡像配對。單一磁碟故障時,陣列仍可持續運作;修復時只需從仍正常運作的配對磁碟直接複製資料,不必重新計算,也不必讀取陣列中的其他磁碟。

RAID 代表獨立磁碟冗餘陣列。它只有一項任務:在磁碟故障或更換期間,維持機器提供服務。這項任務屬於可用性,而可用性不等於安全性。

RAID 會複製你的寫入操作。rm -rf /srv 是一項寫入操作。鏡像的兩個部分會在同一毫秒內刪除該目錄,而陣列事後仍會回報自身狀態正常。

記住這句話。本頁其餘內容將說明各個 RAID level 能承受哪些故障,以及每次寫入會付出什麼代價。最後幾節會介紹如何在你擁有的機器上使用命令查看陣列狀態,以及 RAID 從未涵蓋的故障。

託管服務買家實際會遇到的層級:1、5、6 和 10

方案頁面列出一個數字,通常就此打住。這個數字回答兩個問題:最多可容許幾個硬碟故障,以及每次寫入需要付出什麼代價。

RAID 1 是鏡像。 兩個硬碟儲存完全相同的區塊。每次寫入都會送到兩個硬碟。任一硬碟都能提供讀取服務。一個硬碟故障時不會遺失資料,但原始容量只有一半可用。由於不需要計算同位元,寫入路徑較短。

RAID 5 是在每個 stripe 中加入一個同位元區塊的資料分割。 使用 n 個硬碟時,可取得其中 n-1 個硬碟的容量,且整個陣列可容許恰好一個硬碟故障。同位元不會固定存放在某一個專用硬碟上,而是輪流分布在所有硬碟,因此每個硬碟都同時承載資料與同位元。

RAID 6 會在每個 stripe 中加入第二個獨立的同位元區塊,通常標記為 P 和 Q。它可容許任意兩個硬碟同時故障。這點比表面上更重要,因為第二次故障最常發生在第一次故障的修復期間。

RAID 10 是由鏡像組成的資料分割。 硬碟兩兩建立鏡像,資料再分散到各組鏡像之間。可用容量是原始總容量的一半,與 RAID 1 相同,但額外具備資料分割的平行處理能力。

你也會看到 RAID 1+0 這種寫法,這是較準確的描述:先建立鏡像,再跨鏡像進行資料分割。RAID 0+1 則是相反順序,先建立資料分割,再將兩個 stripe 建立鏡像。這種配置較差,因為一個硬碟故障就會使整個 stripe 停止提供服務,修復時還必須複製另一側的完整內容。

Linux 是值得了解的特殊情況。核心的 raid10 是單一 personality,而不是兩個堆疊的層,因此可使用奇數個硬碟運作,並提供巢狀配置無法表達的配置方式(nearfaroffset)。這就是為什麼 Linux 主機上的狀態列會顯示 2 near-copies,而不是列出兩個陣列。

ChartEight 1 TB drives: usable capacity and drives lost before data loss
The data behind this chart
[
  {
    "label": "RAID 1 (four mirrored pairs)",
    "usable_tb": 4,
    "worst_case_drives_lost": 1,
    "best_case_drives_lost": 4
  },
  {
    "label": "RAID 5",
    "usable_tb": 7,
    "worst_case_drives_lost": 1,
    "best_case_drives_lost": 1
  },
  {
    "label": "RAID 6",
    "usable_tb": 6,
    "worst_case_drives_lost": 2,
    "best_case_drives_lost": 2
  },
  {
    "label": "RAID 10",
    "usable_tb": 4,
    "worst_case_drives_lost": 1,
    "best_case_drives_lost": 4
  }
]

8 個 1 TB 硬碟在 RAID 5 下可提供 7 TB 的可用空間,在 RAID 10 下則為 4 TB。這個差距代表實際成本,也是同位元配置不斷被提出的原因。RAID 6 在任何故障排列下都能容許 2 個硬碟故障。RAID 10 只能保證 1 個,因為最危險的第二次故障,是發生在已故障硬碟的鏡像夥伴上。當沒有兩次故障發生在同一組鏡像時,它最多可容許 4 個硬碟故障;但這取決於運氣,不是設計本身提供的保證。

每次寫入時各層級的成本

寫入 mirror 會變成 2 次寫入,同時發送至兩個成員。寫入 parity stripe 的工作量較大,因為該 stripe 的 parity block 已經失效,必須重新計算。

controller 無法只根據新的 block 重新計算 parity。它必須先取得舊的 data block 與舊的 parity block。因此,RAID 5 的 1 次小型隨機寫入會變成 read、read、write、write。RAID 6 還需要維護第二個 syndrome,因此相同的寫入會變成 read、read、read、write、write、write。

ChartDevice operations per small random write, and drives read during a rebuild
The data behind this chart
[
  {
    "label": "RAID 1 (2 drives)",
    "write_ops_per_host_write": 2,
    "drives_read_to_rebuild": 1
  },
  {
    "label": "RAID 5 (8 drives)",
    "write_ops_per_host_write": 4,
    "drives_read_to_rebuild": 7
  },
  {
    "label": "RAID 6 (8 drives)",
    "write_ops_per_host_write": 6,
    "drives_read_to_rebuild": 7
  },
  {
    "label": "RAID 10 (8 drives)",
    "write_ops_per_host_write": 2,
    "drives_read_to_rebuild": 1
  }
]

在 RAID 6 上,1 次小型隨機寫入會產生 6 次裝置操作;在 RAID 10 上則是 2 次。這些數量仍低估了延遲差異。兩次 mirror 寫入會平行發出,因此 guest 必須等待其中較慢的一次。parity 路徑中的 read 必須先完成,才能計算新的 parity;因此 guest 必須依序等待 1 次 read,再等待 1 次 write。在繁忙的 host 上,該 read 會排在其他人的 I/O 之後。

有一個重要例外。若寫入大小足以填滿整個 stripe,就不需要舊的 data,因為 stripe 中的每個 block 都會被替換。parity 可根據記憶體中現有的資料計算,成本降為額外 1 次寫入。因此,RAID 5 在循序 benchmark 中看起來表現良好,但在多個 tenant 同時產生小型寫入的混合負載下,效能會明顯惡化。請測試實際執行的負載模式:正確 benchmark VPS 磁碟代表在符合實際情況的 queue depth 下執行隨機 I/O,而不是執行 1 個大型 dd

重建是危險環節的原因

Parity 重建必須使用其他所有磁碟重建遺失的磁碟,因此會從第一個區塊讀到最後一個區塊,共讀取 7 個仍可用的磁碟。RAID 10 重建只會讀取 1:故障磁碟的鏡像夥伴磁碟,不會讀取其他磁碟。

這會帶來兩項成本。第一項是時間,因為重建速度受限於最慢的剩餘磁碟,以及其上的 parity 計算。第二項是負載。Parity set 中的每個磁碟在整個重建期間都會忙碌,因此該節點上的每個 guest 在重建完成前都會遭遇較高延遲。RAID 10 只有其中一組磁碟對會忙碌,其他磁碟對仍以正常速度提供服務。

同一期間也存在資料正確性風險。RAID 5 陣列在一個磁碟故障後便不再具備冗餘,因此只要任何剩餘磁碟出現無法讀取的磁區,該資料就無法復原。重建是唯一會讀取每個磁區的操作,也包括一年來沒有人存取過的磁區。已公開的 datasheet 數據顯示,消費級硬碟每讀取 10^14 bits 約有 1 次無法復原的讀取錯誤,而 enterprise NVMe 磁碟則約為每 10^17 bits 1 次,或更佳。這些數據是廠商規格,不是實測結果;但其比例說明了過去「RAID 5 重建會失敗」的警告,原本是針對大型旋轉式硬碟提出的,也說明這項警告在 NVMe 上的適用性弱得多。負載問題則適用於任何儲存媒體。

請透過 scrub 在重建前找出潛在錯誤。Debian 與 Ubuntu 都會為 md array 提供定期 scrub,但不同版本使用的機制不同,因此請先確認目前使用的機制,再手動觸發一次掃描。

systemctl list-timers --all | grep -i mdcheck
ls -l /etc/cron.d/mdadm
echo check | sudo tee /sys/block/md0/md/sync_action
cat /sys/block/md0/md/mismatch_cnt

sync_action 會在掃描完成時回到 idle,而 mismatch_cnt 應讀為 0。鏡像上的非零數值表示兩個副本不一致,而 kernel 無法判定哪一個正確,因為兩個副本都沒有 checksum。有些不一致沒有影響,swap partition 是最常見的來源:kernel 可能正在寫入某個 page,而該 page 同時在其下方發生變更。資料陣列中的計數持續上升,表示應更換磁碟。

為何 VPS 業者在 NVMe 上普遍採用 RAID 10

Hypervisor 節點不只執行一種工作負載。它會執行數十個彼此無關的 guest,而這些 guest 的 I/O 會交錯形成大量小型寫入,彼此之間沒有區域性。這正是 parity 的 read-modify-write 循環成本最高的模式,也是 shared node 全天候面對的模式。

再加上 rebuild 行為,選擇自然明朗。parity node 上的磁碟故障,會讓該主機上的每個 guest 變慢數小時。RAID 10 node 上的磁碟故障,只會拖慢其中一組 mirror,而且複製作業會以磁碟速度循序執行。業者銷售的是不會出現延遲尖峰的服務,因此必須以容量換取這項特性:一半的原始 NVMe 容量會用於 mirror。

磁碟容量的增加也會將選擇推向同一方向。磁碟容量越大,rebuild 所需時間越長;而在 parity 配置中,這段期間正是所有工作變慢且沒有完整保護的時候。這也是虛擬化用的 ZFS 部署會採用由 mirror vdev 組成的 pool,而不是寬幅 raidz 的原因:mirror resilver 只會複製實際使用中的 block,而且只涉及一組磁碟。

這些因素不代表 RAID 10 在所有情況下都正確。backup target 會以長段循序寫入,讀取頻率也低,因此 RAID 6 在這類用途上更划算。它可承受兩次故障,並保留大部分容量。決定因素是工作負載,而不是數字。對於今天要選擇的方案,儲存媒體通常比其上的 layout 更重要,而 從 SATA SSD 升級至 NVMe 所帶來的差異,大於任一種媒體上的 RAID 差異。

如何讀取 /proc/mdstat

請在您擁有該陣列的機器上執行以下操作:專用伺服器、家中的主機,或您自行組裝且連接兩個磁碟區的 VPS。請查看您自己的輸出。以下區塊是範例,特別列出內容,方便您比對實際輸出的格式。

cat /proc/mdstat
sudo mdadm --detail /dev/md0
lsblk -o NAME,SIZE,TYPE,MOUNTPOINTS

狀態正常的四磁碟 RAID 10,輸出通常會接近以下內容。

Personalities : [raid1] [raid10]
md0 : active raid10 nvme3n1p3[3] nvme2n1p3[2] nvme1n1p3[1] nvme0n1p3[0]
      3906764800 blocks super 1.2 512K chunks 2 near-copies [4/4] [UUUU]
      bitmap: 0/30 pages [0KB], 65536KB chunk

unused devices: <none>

其中每個部分都包含資訊。

  • Personalities 列出執行中核心已載入的 md 模組。出現 raid10 只表示程式碼可用,沒有其他含義。
  • md0 : active raid10 是陣列裝置、狀態及 RAID 層級。
  • 後面的名稱是成員。方括號中的數字是裝置在陣列中繼資料的索引,不是該裝置在該行中的位置,也不一定是其插槽。
  • 更換磁碟後,新成員通常會保留高於其所填補插槽的索引,因此 nvme4n1p3[4] 可能位於插槽 2。mdadm --detail 會在其 RaidDevice 欄位中列出實際插槽;需要區分兩者時,請以該欄位為準。
  • 成員後面的 (F) 表示故障。(S) 表示備援磁碟:已存在、閒置,等待其他磁碟故障。
  • 3906764800 blocks super 1.2 是可用大小,單位為 1 KiB 區塊,後面接著中繼資料格式。
  • 512K chunks 2 near-copies 是 stripe chunk 大小及 RAID 10 配置。在此配置中,每個區塊會相鄰保留兩份副本。
  • [4/4] 是陣列預期的成員數,後面接著目前已同步的成員數。
  • [UUUU] 依插槽順序,每個插槽列出一個字元。U 表示該插槽已啟用且已同步。_ 表示該插槽中沒有正常運作的成員。
  • bitmap: 是 write intent bitmap。它記錄當時正在寫入的區域,因此成員離線後重新加入時,只需重新同步這些區域,而不必處理整個磁碟。

發生問題時,[4/3] 和 [UU_U] 的含義

降級的陣列看起來如下。

md0 : active raid10 nvme3n1p3[3] nvme2n1p3[2](F) nvme1n1p3[1] nvme0n1p3[0]
      3906764800 blocks super 1.2 512K chunks 2 near-copies [4/3] [UU_U]

請一起閱讀這兩組方括號。[4/3] 表示四個插槽中有一個未提供服務。[UU_U] 表示是哪一個,因為底線是第三個字元,而插槽編號從零開始,因此插槽 2 已停止運作。(F) 旗標只會在故障磁碟仍連接時標示該裝置。將磁碟從機器拔出後,該名稱會從該行消失,但底線仍會保留。

陣列仍可在這些狀況下提供服務。RAID 10 通常仍可維持接近完整的速度,因此使用者不一定能察覺效能差異。您必須透過監控得知狀態。

grep -i mailaddr /etc/mdadm/mdadm.conf
sudo mdadm --monitor --scan --oneshot --test
systemctl list-units --all | grep -i md

mdadm 套件會安裝監控 daemon,從 /etc/mdadm/mdadm.conf 讀取 MAILADDR。unit 名稱在不同版本之間可能變更,因此請使用最後一個指令尋找,不要自行猜測。--test 執行後會立即為每個陣列傳送一則訊息。執行後收件匣完全沒有訊息,表示郵件傳送路徑故障;真正重要的警示也會以相同方式遺失。

更換磁碟正在重建時,陣列下方會出現進度列。

md0 : active raid10 nvme4n1p3[4] nvme3n1p3[3] nvme1n1p3[1] nvme0n1p3[0]
      3906764800 blocks super 1.2 512K chunks 2 near-copies [4/3] [UU_U]
      [==>..................]  recovery = 12.4% (242012928/1953382400) finish=63.1min speed=452000K/sec

recovery 表示正將陣列重建到替換磁碟。resync 表示對新建立的陣列進行第一次一致性檢查。check 表示您在上方觸發的 scrub。括號中的數值是以 1 KiB 區塊表示的進度,分母是每個裝置的總量;finish 是核心依目前速度估算的剩餘時間。速度上限由 /proc/sys/dev/raid/speed_limit_minspeed_limit_max 設定,其目的在於避免重建工作耗盡正式環境的 I/O 資源。

重建期間的完整 mdadm --detail
/dev/md0:
           Version : 1.2
     Creation Time : Tue Mar 10 09:14:22 2026
        Raid Level : raid10
        Array Size : 3906764800 (3.64 TiB 4.00 TB)
     Used Dev Size : 1953382400 (1.82 TiB 2.00 TB)
      Raid Devices : 4
     Total Devices : 4
       Persistence : Superblock is persistent

       Update Time : Wed Aug  5 11:02:41 2026
             State : clean, degraded, recovering
    Active Devices : 3
   Working Devices : 4
    Failed Devices : 0
     Spare Devices : 1

            Layout : near=2
        Chunk Size : 512K

    Rebuild Status : 12% complete

              Name : storage:0
            Events : 4184

    Number   Major   Minor   RaidDevice State
       0     259        3        0      active sync set-A   /dev/nvme0n1p3
       1     259        7        1      active sync set-B   /dev/nvme1n1p3
       4     259       11        2      spare rebuilding    /dev/nvme4n1p3
       3     259       15        3      active sync set-B   /dev/nvme3n1p3

Number 欄是中繼資料索引,會列在 /proc/mdstat 的方括號中。RaidDevice 欄是插槽,也就是 [UU_U] 字串中的位置。這裡兩者不同,因為裝置 4 取代了原本位於插槽 2 的磁碟。set-Aset-B 表示每個 mirror 的兩個部分;同一組鏡像中,set-A 與 set-B 各有一個成員,且兩者保存相同資料,因此您不得讓這兩個成員同時遺失。

在您擁有的陣列上更換磁碟需要執行四個指令,最後一個指令用於檢查。

sudo mdadm --manage /dev/md0 --fail /dev/nvme2n1p3
sudo mdadm --manage /dev/md0 --remove /dev/nvme2n1p3
sudo mdadm --manage /dev/md0 --add /dev/nvme4n1p3
cat /proc/mdstat

recovery 列應在 1 或 2 秒內出現。替換分割區的大小必須至少等於 mdadm --detail 中的 Used Dev Size。如果分割區小了即使只有些微差異,也會以類似 not large enough to join array 的訊息遭到拒絕。新增替換磁碟前,請先將其分割區配置成與舊磁碟相同。

從 VPS 內部能看見與不能看見的內容

大多數 guest 無法看見主機的 RAID,這是設計如此。hypervisor 會提供一個虛擬磁碟給你。該磁碟是由 NVMe 磁碟組成的 RAID 10 儲存池切分而來,還是位於單一磁碟上,屬於主機的配置,不會顯示在 guest 內部。

systemd-detect-virt
lsblk -d -o NAME,SIZE,ROTA,MODEL
cat /proc/mdstat

systemd-detect-virt 在 KVM guest 上會顯示 kvm,在容器上會顯示類似 lxc 的容器類型,在 bare metal 上則會顯示 none。在 KVM guest 上,通常只能在 lsblk 看到單一的 vdasda,而 /proc/mdstat 中不會有陣列,因為 guest 內部沒有這些陣列。

在以容器為基礎的 VPS 上,這項讀值不可靠。容器共用主機 kernel,而 /proc 的部分內容未納入 namespace,因此其中的資訊可能描述的是主機,而不是分配給你的儲存空間。不要把其中任何資訊視為自身儲存配置的事實。請向供應商確認配置;如果這對你很重要,請要求對方以書面提供答案。

你可以從內部檢查的是所提供磁碟的行為。檢查 VPS 磁碟是否確實為 NVMe 說明可回報實際資訊的指令;SSD VPS 實際包含哪些內容 則說明方案頁面上的標籤所宣稱的內容。

是否應在 VPS 內執行 RAID?

通常不應該,原因在於故障網域。如果您將兩個 volume 連接至同一個 VPS,並使用 mdadm 將其做 mirror,兩個 volume 可能位於同一個實體陣列、同一個 node,並共用同一個電源供應器。這會讓每次寫入的成本加倍,但您原本已具備相同的備援能力;而且只要發生那個真正重要的單一故障,兩份資料仍會同時遺失。

如果服務供應商明確說明這些 volume 位於不同的故障網域,或您使用的是可自行配置磁碟的 dedicated server,這樣做才值得。否則,應將這些精力用於建立離開該機器的資料副本。

RAID 無法防護的情況

RAID 只涵蓋一種事件:磁碟機無法正常運作。以下所有操作都是有效寫入,因此陣列會將其套用至每個副本,並回報自身狀態正常。

  • 刪除。 在錯誤的目錄中執行 rm -rf,或部署指令碼在路徑中使用未設定的變數。陣列會將其視為合法寫入,並執行兩次。
  • 勒索軟體。 加密本身就是寫入操作。正常運作的陣列會將加密後的版本儲存至鏡像的兩端。
  • 損壞的應用程式。 將垃圾資料寫入資料庫的程式錯誤,也會將相同的垃圾資料寫入備援磁碟機。
  • 整個節點。 主機故障,或帳號遭誤停權。陣列可能完全正常,卻同時無法存取。
  • 一週後的自己。 你週一刪除的檔案,週一就會從每個磁碟機消失。只有在此之前建立的副本才能將其還原。

儲存在同一個儲存空間上的快照也不是解決方案。快照可協助處理刪除問題,但會與其所在的陣列一同失效。備份之所以是備份,關鍵在於它位於其他位置。使用 restic 建立加密的伺服器外備份 是本頁的另一個重點:陣列讓你能在磁碟機故障時持續提供服務,而當損害來自陣列欣然接受的寫入操作時,restic 能取回你的資料。

FAQ

RAID 10 是否代表不需要備份?

不代表。RAID 10 可防止磁碟停止運作。每次有效寫入都會套用至鏡像的兩個部分,因此刪除操作或勒索軟體執行結果會在同一時間寫入備援磁碟。之後陣列仍會回報狀態正常,因為就陣列的觀點而言,沒有任何元件故障。您仍需要存放在該機器之外的副本,也仍應偶爾還原副本,以確認副本可正常使用。

VPS 供應商為何選擇 RAID 10,而不是 RAID 5 或 RAID 6?

原因有兩個,且都與小型隨機寫入有關。奇偶校驗寫入必須先讀回舊資料與舊奇偶校驗,才能計算新的奇偶校驗。因此,在 RAID 5 中,小型寫入需要 4 次作業;在 RAID 6 中需要 6 次;鏡像則只需要 2 次。奇偶校驗重建還必須從頭到尾讀取每個仍正常運作的磁碟,導致節點上的每個 guest 受到數小時的效能影響;RAID 10 重建則只需將一個磁碟複製到另一個磁碟,其他磁碟配對不受影響。供應商必須以容量承擔這項取捨:可用原始 NVMe 容量只有一半。

/proc/mdstat 中的 [U_] 或 [UU_U] 代表什麼?

每個字元代表陣列中的一個插槽,依插槽順序排列,每個插槽對應一個字元。U 表示該插槽包含一個已啟用且已同步的成員。_ 表示該插槽中沒有正常運作的成員。在雙磁碟鏡像中,[U_] 表示第二個插槽已離線,且不再具備備援能力。請搭配前方的成對資訊一起閱讀;其中 [4/3] 表示陣列預期有 4 個成員,目前有 3 個。插槽順序對應 mdadm --detailRaidDevice 欄,而不是該行上裝置名稱的顯示順序。

RAID 10 陣列可以遺失多少個磁碟?

在任何故障分布下,都能遺失 1 個。超過 1 個後,取決於故障發生的位置。每個鏡像配對可遺失其中 2 個成員中的 1 個,因此 8 磁碟陣列在沒有 2 個故障落在同一配對時,最多可承受 4 個故障;若 2 個故障都落在同一配對,則 2 個故障就會使陣列失效。請以保證可承受的數量,也就是 1 個,作為規劃基準;超過此數量只能視為運氣,不能視為防護能力。

我應該使用 mdadm,在 VPS 內鏡像 2 個 volume 嗎?

通常不應該。連接至同一個 VPS 的 2 個 volume,通常位於同一台主機上的同一個實體陣列。因此,鏡像會使每次寫入的成本加倍,卻無法防範主機自身 RAID 已涵蓋的任何故障。只有在供應商明確說明這些 volume 位於不同故障域時,這樣做才有價值。否則,應將這些資源投入存放在該機器之外的備份。