iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0
IT Operation

AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨系列 第 19 篇

Day 19|檔案該放 S3、EBS 還是 EFS?

  • 分享至 

  • xImage
  •  

上一篇透過 VPC Peering,驗證了跨 VPC 通訊需要配合路由與 Security Group 設定。

網路連通之後,接下來要處理的是資料:應用程式產生的圖片、報表與上傳檔案,應該放在哪裡?

AWS 常見的選擇包括:

  • Amazon S3
  • Amazon EBS
  • Amazon EFS

三個服務都能儲存資料,但應用程式使用它們的方式不同,選擇之前,比起先問「有多少 GB」,更重要的是:應用程式到底要怎麼讀寫這份資料?


先看應用程式怎麼讀寫資料

假設有一個網站,會把使用者上傳的圖片寫進:

/uploads/product.jpg

只有一台 EC2 時,檔案存在這台主機的磁碟裡,看起來沒有問題。

但當網站擴展成兩台 EC2,放在 ALB 後面,就可能發生:

  1. 上傳請求被分配到 EC2 A,圖片存進 A 的磁碟。
  2. 下一次讀取請求被分配到 EC2 B。
  3. B 的相同路徑沒有那張圖片,因此讀取失敗。

即使兩台 EC2 的網路互通,也不代表它們會自動共用檔案。

這時候,選型要回到應用程式的讀寫方式:

服務 儲存類型 應用程式如何存取 常見用途
S3 Object Storage(物件儲存) 透過 API、SDK 或 HTTP 請求存取物件 圖片、影片、報表、備份
EBS Block Storage(區塊儲存) 掛載到 EC2,由作業系統建立檔案系統後使用 系統磁碟、應用程式資料磁碟、自建資料庫
EFS File Storage(檔案儲存) 透過 NFS 掛載,共用檔案與目錄 多台 Linux 主機共用上傳目錄或應用程式檔案

同樣是一張圖片,可以存在三種服務裡;真正不同的是,程式要怎麼取得它,以及誰負責維持資料的存取方式。


S3:讓應用程式透過 API 存取物件

前面的跨帳號實作其實已經使用過 Amazon S3,例如:

aws s3api get-object \
  --bucket shared-product-data-prod \
  --key products/product.json \
  /tmp/product.json

這個指令會向 S3 取得 Key 為 products/product.json 的 Object(物件),再下載到 EC2 的 /tmp/product.json,它並沒有把 S3 Bucket 掛載成主機上的磁碟。

在一般用途的 S3 Bucket 中,資料以 Object 儲存,每個物件透過 Object Key(物件鍵) 識別。例如:

images/products/product-001.jpg

在 S3 主控台中,這個名稱看起來像是 images 資料夾裡有一個 products 資料夾,再放入 product-001.jpg。

但對 S3 而言,images/products/product-001.jpg 整段才是完整的 Object Key ,其中的 images/ 與 images/products/ 是 Prefix(前綴),可以用來分類與列出物件,不是傳統檔案系統中真正的目錄。

這個差異會影響應用程式的寫法,原本把圖片存進 /uploads 的網站,改用 S3 後可以調整成:

  1. 應用程式透過 SDK,把圖片上傳到指定 Bucket。
  2. 資料庫記錄 Object Key,例如 images/products/product-001.jpg。
  3. 需要圖片時,再依 Bucket 與 Object Key 取得物件,或透過預先簽署 URL、CloudFront 提供存取。

如此一來,不論請求被分配到 EC2 A 還是 EC2 B,都能存取同一份物件,不必把圖片複製到每台主機,新增或替換 EC2 時,也不需要搬移這些上傳檔案。

商品圖片、影片、報表與備份等資料,都很適合從這種方式評估,如果應用程式可以使用物件 API,而且不需要共享檔案系統的操作方式,就可以優先考慮 S3。

但也會有需要承擔的責任,像是整合物件 API,並設計存取權限、版本保留與刪除規則等。


EBS:提供 EC2 使用的磁碟

如果需求不是「存一個 Object」,而是應用程式需要主機上的磁碟,例如作業系統、套件安裝位置,或自建資料庫的資料目錄,就比較接近 Amazon EBS(Elastic Block Store)。

EBS 提供的是 Block Storage(區塊儲存),以 Linux 資料磁碟為例,通常需要:

  1. 建立 EBS Volume。
  2. 附加到 EC2。
  3. 建立檔案系統,例如 XFS 或 ext4。
  4. 掛載到 /data 等路徑。

之後應用程式就可以透過一般檔案操作讀寫資料,所以 EBS 比較像是提供 EC2 使用的持久化磁碟。

但有一個會直接影響架構的限制:EBS Volume 與使用它的 EC2,必須位於相同 AZ。

如果應用程式分散在兩個 AZ,就不能把其中一個 AZ 的 EBS Volume,直接掛到另一個 AZ 的 EC2 上使用。

EBS 也不適合直接拿來解決前面的「多台網站主機共用上傳目錄」問題。

雖然部分 io1、io2 Volume 支援 Multi-Attach(多重附加),可以同時附加到同一個 AZ 的多台 EC2,但這不代表它就變成一般的共享檔案系統,一般的 ext4、XFS 也並不是為多台主機同時寫入同一個 Volume 而設計的。

使用 EBS 時,也要規劃容量、IOPS、吞吐量與快照設定等,AWS 管理底層儲存設備,但檔案系統、應用程式資料一致性與復原流程,仍然需要自行處理。


EFS:多台主機共用同一個檔案系統

如果既有程式就是要讀寫:

/uploads/product.jpg

而且短期內不方便改成 S3 API,這時可以評估 Amazon EFS(Elastic File System)。

EFS 提供的是共享 File Storage(檔案儲存),透過 NFS(Network File System,網路檔案系統) 讓多台 Linux EC2 可以掛載同一個 EFS、各台主機使用相同的目錄與檔案。

例如:

                 ALB
                  │
        ┌─────────┴─────────┐
        ▼                   ▼
      EC2 A               EC2 B
        │                   │
        └─────────┬─────────┘
                  ▼
                 EFS
                  │
           /shared/uploads

以前面的網站為例,兩台 EC2 都把同一個 EFS 掛載到 /uploads:

  • A 寫入圖片後,B 可以從共享檔案系統讀取。
  • 新增 EC2 時,可以掛載同一個 EFS,不必另外複製整個上傳目錄。
  • 替換應用程式主機時,檔案不必跟著主機搬移。

這能保留原本的檔案路徑操作方式,但使用前還是需要處理網路與權限。

EFS 透過 Mount Target(掛載目標) 提供 VPC 內的連線入口,Security Group 也必須允許用戶端存取 NFS 使用的 TCP 2049;掛載成功後,檔案與目錄的 POSIX 權限也會影響程式能否讀寫,網路能連上,不代表執行程式的使用者就有檔案寫入權限,這也跟我在前面網路篇一直有提到的概念十分相似。

另外,EFS 有兩種需要區分的檔案系統類型:

  • Regional:資料冗餘儲存在同一個 Region 的多個 AZ。
  • One Zone:資料儲存在單一 AZ。

如果前面已經要求應用程式能承受單一 AZ 故障,我會選擇 Regional EFS,並在應用程式使用的 AZ 規劃掛載目標,而不會只看到「EFS」就假設所有配置都有相同的故障承受能力。

EFS 也不會自動解決所有並行寫入問題,如果兩個程式同時修改同一份檔案,仍然需要適當的鎖定或應用程式協調;既有程式改用網路檔案系統後,也應測試實際讀寫延遲,尤其是大量小檔案或頻繁開關檔案的工作負載。


同樣是上傳檔案,什麼條件會改變選擇?

回到最前面的網站,以下用一個假設情境比較。

網站目前有兩台跨 AZ 的 EC2,使用者上傳的圖片必須能被兩台主機讀取,乍看之下 S3 和 EFS 都可以解決「資料不要只存在 EC2 A」這件事,真正影響選擇的是 Application 怎麼使用這份資料。

條件 可優先選擇 需要承擔的管理責任
新開發的上傳功能,可以使用 SDK 存取物件 S3 整合物件 API,設計授權與物件生命週期
既有程式必須讀寫 /uploads,多台主機需要共享 EFS Regional 管理掛載、網路與檔案權限,驗證並行讀寫行為
資料只供單台 EC2 使用,需要主機磁碟介面 EBS 規劃容量與效能,管理檔案系統、快照與復原

如果這是可以調整程式的新功能,那可以優先選擇 S3,讓上傳資料不依附任何一台 EC2。

在「多台應用程式需要存取相同圖片,而且程式可以使用物件 API」的條件下,我會優先選擇 S3,讓各台主機透過相同的物件位置讀寫資料;同時就需要接受應用程式需要整合 API、存取授權與物件管理流程的責任。

但如果是短期內不能修改的既有系統,則可以改選 EFS Regional,保留共享目錄的操作方式。

EBS 在這個跨 AZ 共享上傳目錄的需求中,就不是合適的選項:它的掛載範圍與共享方式,都不符合這次要解決的問題。

三個服務也可以同時出現在一套系統裡,例如 EC2 用 EBS 作為系統磁碟,上傳圖片放在 S3,少數必須共享檔案路徑的元件使用 EFS,選擇的單位應該是資料用途,而不是替整個系統只選一種儲存服務。

最後還要接回 Day 17:資料能被多台主機存取,或儲存在多個 AZ,不代表誤刪之後一定救得回來。 版本保留、備份與還原演練,仍然要依資料的重要程度另外規劃。


下一篇

今天從物件、區塊與共享檔案的存取方式,選擇適合的儲存服務。

但訂單、會員與庫存資料,除了保存之外,還需要查詢、更新與交易處理,下一篇會比較 Amazon RDS、Amazon Aurora 與 Amazon DynamoDB,看看資料模型與查詢方式,如何影響資料庫的選擇。

參考資料


上一篇
Day 18|VPC Peering 實作:建立連線後,為什麼還是連不通?
下一篇
Day 20|資料庫該選 RDS、Aurora,還是 DynamoDB?
系列文
AWS 架構為什麼這樣選?30 天拆解服務選型與設計取捨 共 22 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言