物件儲存 (Blob Storage)
Blob Storage 是放大型二進位資料(圖片、影片、PDF、備份、ML 模型)的地方。
心法:二進位資料不進資料庫 —— DB 存 metadata(key、大小、狀態),Blob Storage 存實際 bytes。
取捨核心:用就地修改 + 低延遲隨機存取,換極高耐久性 + 近乎無限擴展 + 低成本。
Blob 是什麼
Blob(Binary Large Object) = 任何大型二進位資料。**Blob Storage(物件儲存,Object Storage)**專門存這類資料。代表產品:AWS S3、GCS、Azure Blob Storage。
面試只要題目出現「用戶上傳的內容」,第一反應就是:這個放 Blob Storage,不放資料庫。
三種儲存方式對比
| 類型 | 組織方式 | 存取單位 | 就地修改 | 延遲 | 代表 |
|---|---|---|---|---|---|
| File Storage(檔案) | 樹狀目錄,用路徑找 | 檔案(可改幾行) | ✅ | 中 | NFS、SMB、EFS |
| Block Storage(區塊) | 切成固定大小 block | 第 N 號到第 M 號 block | ✅ | 低 | EBS、Persistent Disk |
| Object Storage(物件) | 扁平,用 key 取整個 | 整個物件(不可改一部分) | ❌ | 高 | S3、GCS |
你不能就地改物件的一部分,只能上傳新版本替換。沒有真正的資料夾,users/123/avatar.jpg 看起來像路徑,但只是 key 的命名慣例(前綴),底層是扁平字串。
正是「不可變 + 扁平 + 整體存取」讓它做到一般檔案系統做不到的:極高耐久性、近乎無限水平擴展、全球複製、低廉成本。代價是放棄就地修改與低延遲隨機存取。
核心概念:Bucket 與 Object
Bucket 是最頂層容器(Azure 叫 Container)。全球唯一名稱,綁定一個 Region,資料不會自動跨 Region 複製(除非明確設定)。
Object 由三部分組成:
| 組成 | 說明 |
|---|---|
| Key | Bucket 內唯一識別碼(扁平字串,例 uploads/2026/03/photo.jpg) |
| Data | 實際二進位內容,幾 bytes ~ 幾 TB |
| Metadata | 鍵值對(Content-Type、Cache-Control、自訂 x-uploaded-by) |
耐久性 vs 可用性(兩件不同的事)
| 指標 | S3 Standard | 意義 |
|---|---|---|
| 耐久性 Durability | 99.999999999%(11 個 9) | 資料不會消失:存 1,000 萬個物件,一年預期損失 < 1 個 |
| 可用性 Availability | 99.99% | 你能否存取到資料(偶爾服務中斷,但資料還在) |
怎麼做到 11 個 9?底層跨 3 個 AZ(可用區)冗餘儲存,一個 AZ 全毀也不丟資料。AZ = 獨立電力與網路的資料中心。
一致性
現代 S3(2020 後):PUT / DELETE 強一致 —— 上傳後立刻讀,保證讀到最新版本
分散式物件儲存設計:最終一致仍是核心概念 —— 短暫不一致,最終所有副本一致
自建/全球複製的物件儲存往往選 AP(可用性 + 分區容忍) 而非 CP。面試若談到全球複製或自建分散式儲存,這個取捨會再出現。詳見 02-Distributed-Systems/02-CAP-Theorem。
儲存分層(Storage Tier)
成本模型按存取頻率分層。核心取捨:儲存越便宜,取回越貴。
| 等級 | 適合場景 | 取回延遲 | 儲存成本 | 取回費用 |
|---|---|---|---|---|
| Standard(熱) | 頻繁存取 | 毫秒 | 最高 | 無 |
| Infrequent Access(溫) | 每月幾次 | 毫秒 | 中 | 有 |
| Glacier Instant | 每季一次 | 毫秒 | 低 | 較高 |
| Glacier Flexible | 備份,幾小時取回 | 分鐘~小時 | 很低 | 更高 |
| Glacier Deep Archive | 長期歸檔 | 最長 12h | 最低 | 最高 |
但如果突然要大量取回,取回費用可能遠超你省下的儲存成本。冷儲存只適合「真的很少取回」的資料。
生命週期策略(Lifecycle Policy)
手動管理每個物件的等級不現實 → 用生命週期規則自動降級:
uploads/ 前綴:
30 天後 → Standard-IA
90 天後 → Glacier
365 天後 → Deep Archive
2555 天 → 直接刪除(Expiration)
面試問「歷史資料 / 日誌怎麼處理?怎麼控成本?」→ 生命週期策略就是答案,不需要任何應用層干預。
存取控制
| 機制 | 類型 | 控制什麼 |
|---|---|---|
| IAM Policy | 基於身份 | 哪個用戶/角色能對哪個 Bucket 做什麼操作 |
| Bucket Policy | 基於資源 | 直接附在 Bucket 上,可控跨帳號、強制加密 |
物件預設私有。S3 資安事件報告中,公開 Bucket 的設定錯誤佔資料外洩很大比例。
正確做法:Bucket 保持私有,透過 Presigned URL 授予有時限的個別物件存取 —— 後端簽名產生的臨時 URL,帶到期時間,過期自動失效。(細節見 10-Design-Patterns/04-Handling-Large-Blobs)
版本控制(Versioning)
啟用後,同一 key 上傳新物件,舊版本不覆蓋而是保留並給新 Version ID:
users/123/avatar.jpg (v3, 最新)
users/123/avatar.jpg (v2)
users/123/avatar.jpg (v1)
好處:防誤刪(DELETE 只加刪除標記,舊版仍在)、應用層回滾、覆寫保護。代價是所有歷史版本都收費 → 通常搭生命週期規則自動清理舊版。
面試問「怎麼確保重要資料不被誤刪?怎麼支援回滾?」→ 啟用版本控制。
跨區域複製(CRR, Cross-Region Replication)
預設只在單 Region 內跨 AZ 複製,不跨 Region。要全球副本需明確設 CRR:
| 為什麼需要 CRR | 說明 |
|---|---|
| 災難恢復 DR | 整個 Region 出事仍能服務 |
| 法規遵循 | 資料須備份在地理分離位置(或反向:不能離境) |
| 讀取延遲優化 | 亞洲用戶讀亞洲副本,減少跨洋延遲 |
上傳到主 Region 後幾秒~幾分鐘複製到目標 Region,不是即時同步。雙向複製時同一 key 幾乎同時被改 → 預設「最後寫入者勝出」,要確認符合業務邏輯。要強一致的地理複製,CRR 不夠。
Blob Storage 在架構中的角色
| 角色 | 模式 |
|---|---|
| 非結構化資料層 | DB 存 metadata(url、大小、狀態)+ S3 存實際 bytes,各司其職 |
| 資料管線中繼站 | 原始影片→S3 →(S3 Event)→ 轉碼 Lambda→S3 →(Event)→ 縮圖 Lambda,步驟解耦 |
| 靜態資源來源 | HTML/CSS/JS/圖片放 S3,前面掛 CDN(CloudFront)邊緣快取分發 |
| Data Lake 底層 | 日誌→Kinesis→S3(Parquet),Athena/Spark 直接查 S3,免搬進倉儲 |
用戶上傳頭像
→ API Server 把圖片存 S3 (key: users/{id}/avatar.jpg)
→ API Server 把 metadata 寫 DB (user_id, avatar_url, updated_at)
讀取:DB 回 avatar_url → 客戶端直接從 S3 / CDN 取圖
「圖片存 S3,前面掛 CloudFront。第一次存取從 S3 拉並快取到最近邊緣節點,之後直接從邊緣取,延遲從幾百毫秒降到個位數毫秒,S3 流量也大幅下降。」
常見面試情境
| 系統 | 設計要點 |
|---|---|
| IG / Twitter | 圖片/影片經 Presigned URL 直傳 S3(server 不碰 bytes);30 天 Standard、舊用 IA、>2 年 Glacier;CloudFront 分發 |
| Dropbox / Drive | 備份天然偏冷 → S3 Intelligent-Tiering 自動移到最便宜層;明確歷史備份直接 Glacier |
| 日誌 / 監控 | 日誌→Kinesis Firehose→每小時壓 Parquet 存 S3,Athena 跑 SQL;生命週期自動歸檔 |
| 電商 | 商品圖 Standard + CloudFront;訂單 PDF 收據用 IA;年度財報合規歸檔 Deep Archive |
常見 Deep Dive
用資料庫:需多欄位查詢(WHERE user_id=123 AND status='active')、需 ACID、結構化有 schema、資料小(幾 KB 內)。
用 Blob Storage:大型二進位、只按 key 取整個物件、需極高耐久性 + 低成本、寫入後很少修改。
粗略標準:超過幾 MB 且不需 SQL 查詢 → Blob Storage。DB 存 metadata,Blob 存內容。
四道防線:① 預設封鎖所有公開存取(Bucket + 帳號層級);② 私有 Bucket + Presigned URL(不要整桶公開);③ S3 Access Analyzer 持續掃描標記意外公開的 Bucket;④ 最小權限 IAM(只需上傳特定前綴就別給讀整桶)。
- 讀多寫少(靜態/媒體):CDN 是最直接解,S3 當 origin,邊緣快取,不需跨 Region 複製 S3。
- 需跨 Region 讀寫:用 CRR,各 Region 從自己副本讀(低延遲),寫在主 Region。
- 合規不能離境:CRR 的反向需求 —— 用 Bucket Policy 拒絕跨 Region 複製、鎖定 Region。
陷阱題:物件儲存不支援按內容搜尋(不能 SELECT WHERE 內容包含貓)。
原則:S3 是儲存的地方,不是搜尋的地方。需要搜尋的屬性都要在適合搜尋的系統裡建索引:
- metadata 查詢 → 存關聯式 DB,SQL 查出 S3 key 再取物件
- 全文搜尋 → Lambda 提取文字(PDF 解析/OCR)→ 索引到 08-Search-and-AI/03-Elasticsearch
- 以圖搜圖 → ML 轉 embedding → 存 08-Search-and-AI/04-Vector-Database
自我測驗重點
| 問題 | 重點 |
|---|---|
| File / Block / Object 差異 | Object = 扁平 + 不可變 + 以 key 取整個 |
| 耐久性 vs 可用性 | 11 個 9(不丟)vs 99.99%(能不能存取) |
| 儲存分層核心取捨 | 越便宜取回越貴;用生命週期自動降級 |
| 防公開曝露 | 預設封鎖公開 + 私有 + Presigned URL |
| 防誤刪 / 回滾 | 版本控制(Versioning) |
| 全球讀多寫少 | CDN(不必跨 Region 複製 S3) |
| 二進位資料放哪 | Blob Storage,DB 只存 metadata |
Related Notes
- 07-Caching-Storage/01-Caching — CDN 是 Blob Storage 之前的加速層;快取與儲存同屬資料層
- 10-Design-Patterns/04-Handling-Large-Blobs — Presigned URL 直傳、Multipart、CDN download 的完整模式
- 01-Networking/06-Load-Balancing — CDN 邊緣分發屬負載/加速範疇
- 02-Distributed-Systems/02-CAP-Theorem — 物件儲存全球複製是 AP 取捨
- 06-Database-Tech/01-Database — Blob Storage 是「單純檔案儲存」的正確選擇,別塞進 DB
- 11-Infrastructure/04-Serverless — S3 Event → Lambda 的事件驅動處理管線
- 08-Search-and-AI/03-Elasticsearch、08-Search-and-AI/04-Vector-Database — 在 Blob 上做搜尋的索引去處
- 07-Caching-Storage/Practice-Caching-Storage