為什麼物件儲存#

「給我一塊地方放檔案」── 看似簡單,傳統 NFS 撐不住現代規模:

  • 數十億物件
  • 跨地域、跨機房
  • TB ~ PB 級單客戶
  • 多副本、跨區複製、版本控制
  • 公網直接訪問(給 CDN 拉)

物件儲存(S3、阿里 OSS、騰訊 COS、MinIO)為這個場景設計。它的特點:

  • 扁平命名空間:沒有真正的目錄,key 是字串
  • REST API:HTTP PUT/GET/DELETE
  • immutable:物件可覆蓋,但不能 append(少數系統有限制 append)
  • 多版本:可選保留歷史
  • 元資料:附加 KV,不是 inode

與其他儲存的區別#

系統介面特點
區塊儲存磁區讀寫給 DB / VM 用,掛載成 block device
檔案儲存POSIX給應用直接用,支援 mkdir/chmod 等
物件儲存HTTP REST給應用透過 SDK 用,超大規模、便宜

物件儲存犧牲了 POSIX 的 rich API(沒 random write、無 inode、無 fsync 語意)換到了:

  • 單 bucket 數十億物件
  • 跨區複製
  • 11-9s 耐久性(99.999999999%)
  • 按用量付費

內部架構#

S3 / 內部物件儲存的概念架構:

                    Client
                      │
                 HTTP request
                      ▼
              ┌───────────────┐
              │  Gateway / LB │
              └───────┬───────┘
                      ▼
              ┌───────────────┐
              │  Metadata DB  │   <- key → 物件 metadata(位置、大小、checksum)
              └───────┬───────┘
                      ▼
              ┌───────────────┐
              │ Storage nodes │   <- 實際 chunk 散在多台機器
              │  (Chunk OSDs) │
              └───────────────┘

寫入流程(簡化):

  1. Client 發 PUT /bucket/key 帶資料
  2. Gateway 把資料切成 chunks
  3. 每個 chunk 用一致性 hash 決定送到哪幾個 storage node(多副本或 erasure code)
  4. 寫成功 → 寫 metadata DB
  5. 回應 client 200 OK

讀取流程:

  1. Client GET /bucket/key
  2. Gateway 查 metadata
  3. 根據 metadata 知道 chunk 在哪些 node
  4. 並行讀回 chunks,組裝成完整物件 stream 給 client

大檔案如何拆與存#

一個 1 GB 的影片不會存成單一 file:

原始物件 (1 GB)
    │
    ▼  切分成 chunks(典型 4 ~ 64 MB 一塊)
[chunk 1][chunk 2][chunk 3]...[chunk N]
    │
    ▼  每個 chunk 多副本或 EC
chunk 1 → node A, B, C(3 副本)
chunk 2 → node D, B, F
chunk 3 → ...

幾個重要設計:

1. chunk 大小#

太小:metadata 暴漲、每個請求要 lookup 太多 chunk 太大:一次失敗影響大

實務:4 MB ~ 64 MB。HDFS 預設 128 MB(block size)。

2. 副本 vs Erasure Code#

方式空間放大故障恢復成本
3 副本同 chunk 存 3 台機器3x直接複製
EC (10+4)10 data + 4 parity1.4x計算重建(CPU)

冷資料用 EC(省 50% 成本)、熱資料用副本(讀快)。

3. 一致性 hash 分配#

用 chunk 的 hash 決定哪個 node:

hash(chunk_id) → ring位置 → 3 個最近的節點(順序往下)

新增節點 → 只有部分 chunk 需要搬遷(環上鄰近段)。

多部分上傳(Multipart Upload)#

大檔上傳:

  1. Init:client 通知 server 要開始一個大上傳,回傳 upload_id
  2. Upload Parts:client 把檔案切成 N 部分,並行上傳每個 part(帶 upload_id + part_number)
  3. Complete:所有 part 完成後,client 通知 server 「合併」── server 把 parts 拼成最終物件
PUT /bucket/key?uploads
→ uploadId = "abc"

PUT /bucket/key?partNumber=1&uploadId=abc
PUT /bucket/key?partNumber=2&uploadId=abc
PUT /bucket/key?partNumber=3&uploadId=abc

POST /bucket/key?uploadId=abc
  → 完成

優點:

  • 並行上傳加速
  • 失敗只重傳該 part
  • 可暫停與恢復

對 1 GB 以上的檔案幾乎必走 multipart。

metadata 服務的設計#

物件儲存的「擴容性」核心其實是 metadata。資料量達 PB 時,metadata 自己有幾百 GB ~ TB。

設計選擇:

  • 集中式 KV:用 LSM-tree DB(RocksDB-based、tikv)。簡單但要分片
  • 分散式 KV:DynamoDB-style 分散
  • 客戶側 hash + 預先分區:bucket 名直接決定 metadata shard

S3 內部用了一套自己的 metadata 系統,採極端擴容性設計。MinIO 等開源是輕量化版本。

一致性模型#

S3 在 2020 之前是「讀 your-own-write 強一致、其他最終一致」── 上傳成功後,自己讀立刻看到,但別人可能還看不到。

2020 年後 S3 升級為強一致(PUT 後的 LIST 也立刻看到)。

對應用:

  • 寫進物件 + 寫 DB metadata → 配合好順序
  • 別假設 HEAD 與 GET 一定一致
  • list bucket 是貴操作(按 prefix 掃 metadata)

安全與權限#

bucket policy
+ ACL(傳統,較老)
+ IAM policy(雲端方案)
+ pre-signed URL(時效性連結)

電商常用 pre-signed URL:用戶要上傳照片,伺服器生成一個 5 分鐘有效的 PUT URL,用戶直接 PUT 到物件儲存,不經過你的伺服器:

1. user → server: 「我要上傳頭像」
2. server → user: 「PUT to https://bucket.s3.amazonaws.com/...?signature=xxx」
3. user → S3: 直接 PUT

伺服器卸下大量流量,安全性靠簽名 URL 限時。

CDN 整合#

物件儲存 + CDN 是電商標配:

hot files (商品圖):物件儲存 ─→ CDN ─→ 用戶
cold files (備份):物件儲存 ─→ 直讀

多數雲端 CDN(CloudFront、阿里 CDN)原生整合自家物件儲存。設計時把 bucket 當 origin,CDN 自動處理 caching、邊緣分發、TLS。

生命週期管理#

「3 個月以前的圖片自動轉冷層」── 自動化,不手動搬:

LifecycleConfiguration:
  - ID: archive-old
    Status: Enabled
    Filter:
      Prefix: "products/"
    Transitions:
      - Days: 30
        StorageClass: STANDARD_IA # infrequent access
      - Days: 90
        StorageClass: GLACIER # 冷存
    Expiration:
      Days: 365 # 一年後自動刪

對備份、log、媒體存檔極有用。冷層便宜 5~10x。

自建 vs 公雲#

維度自建(MinIO / Ceph)公雲(S3 / OSS)
起步成本機房 + 機器0
擴展性自己擴自動
運維全包雲廠商
跨地容災自己搭內建
法規 / 隱私完全控制有合規但他人託管
出網成本0高(S3 egress 是大頭)
適合極大規模、特殊合規90% 場景

對中型電商,用公雲 通常是對的。除非:

  • 自有機房優勢明顯
  • 出網流量極大(CDN 命中率高反而不痛)
  • 法規禁止(特定行業 / 區域)

物件儲存也是 data lake 基底#

近年趨勢:

  • 資料湖(S3 + Parquet)取代傳統資料倉儲
  • AI 訓練資料存在物件儲存
  • 容器映像存在物件儲存(Docker registry backend)
  • 備份目的地

S3 已經不只「存檔案」,而是現代資料架構的基底

小結#

  • 物件儲存為超大規模、扁平命名、HTTP API 設計
  • 大檔拆 chunk → 多副本 / EC → 一致性 hash 分配
  • 大檔上傳用 multipart,支援並行 / 重試
  • 對應用:用 SDK 或 pre-signed URL,不過你的伺服器
  • 配 CDN 是基本功
  • 生命週期管理自動化冷熱搬遷
  • 公雲 vs 自建:90% 場景公雲

下章看更大尺度的儲存管道:Kafka、HDFS、OLAP 系統。