OpenStack Swift对象存储详解

发表于
更新于
3 14.1~18.1 分钟 6351

OpenStack Swift对象存储详解

一、Swift核心架构概览

Swift 是 OpenStack 的分布式对象存储核心组件,为云平台提供高可用、可扩展、低成本的非结构化数据存储。由 Rackspace 开发并于 2010 年贡献给 OpenStack 社区,使用普通硬件即可构建 PB 级存储集群,无需 RAID,通过软件层面的一致性哈希与多副本机制保障数据安全。🗄️

架构全景图

                       ┌──────────┐
                       │ Keystone │
                       └────┬─────┘
                            │ AUTH
                       ┌────▼─────┐
  USER ──HTTP REST────►  PROXY   │
  (PUT/GET/DELETE)    │ SERVER  │
                       └────┬─────┘
                            │ Ring Lookup
                            │
              ┌─────────────┼─────────────┐
              ▼             ▼             ▼
        ┌──────────┐ ┌──────────┐ ┌──────────┐
        │ACCOUNT   │ │CONTAINER │ │ OBJECT   │
        │ SERVER   │ │ SERVER   │ │ SERVER   │
        └────┬─────┘ └────┬─────┘ └────┬─────┘
             │            │            │
        ┌────▼────┐ ┌────▼────┐ ┌────▼────┐
        │ SQLite  │ │ SQLite  │ │  XFS    │
        │ Account │ │Container│ │Object   │
        │   DB    │ │   DB    │ │  File   │
        └─────────┘ └─────────┘ └─────────┘
                             │
              ┌──────────────┼──────────────┐
              ▼              ▼              ▼
         Replicator      Updater        Auditor
          (rsync)      (异步更新)      (完整性审计)

核心组件一览表

组件 职责 说明
Proxy Server RESTful API 入口网关 校验令牌、查询 Ring 路由请求,无状态可横向扩展
Account Server 账户元数据服务 管理账户内容器列表,存储在 SQLite 数据库中
Container Server 容器元数据服务 管理容器内对象列表,跟踪对象计数与字节总量
Object Server 对象存储服务 对象数据的存储/检索/删除,文件 + xattr 元数据
Replicator 副本同步守护进程 采用 Push 模式,通过 rsync 检测并校正副本不一致
Updater 异步更新守护进程 处理高负载下失败的容器/账户更新(最终一致性的来源)
Auditor 完整性审计守护进程 扫描对象/容器/账户完整性,隔离损坏数据并触发修复
Account Reaper 账户回收守护进程 异步删除标记为删除的账户及其所有容器和对象

架构设计哲学 — 完全对称 + 最终一致性

对象存储设计理念:

┌─────────────────────────────────────────────────────┐
│  控制路径 (Control Path)                              │
│  ├── Proxy Server → Ring 查询 → 路由请求               │
│  ├── Token 鉴权(Keystone 对接)                       │
│  └── 无状态设计,所有节点对等                           │
├─────────────────────────────────────────────────────┤
│  数据路径 (Data Path)                                 │
│  ├── 对象数据直接写入 Object Server                    │
│  ├── Replicator 后台异步同步副本                       │
│  ├── Updater 异步更新容器/账户列表                      │
│  └── Auditor 定期扫描修复                              │
├─────────────────────────────────────────────────────┤
│  CAP 理论定位: AP + 最终一致性                         │
│  ├── 可用性 (Availability): ✅ 高可用                  │
│  ├── 分区容忍 (Partition Tolerance): ✅ 支持            │
│  └── 一致性 (Consistency): 最终一致(R+W > N 保证)    │
└─────────────────────────────────────────────────────┘

关键设计理念: Swift 不追求强一致性,而是通过 Quorum 仲裁 + 后台守护进程实现最终一致性。副本写入不要求全部成功即可返回,不一致状态由 Replicator/Updater 从后台修复。这种设计使得 Swift 在普通硬件上支持无限水平扩展和高可用性。🚀


二、Account / Container / Object 三层数据模型 🧱

Swift 采用完全对称、面向资源的分层架构,数据模型共设三层逻辑隔离:

Account (账户/租户)
   └── Container (容器)
          └── Object (对象)
层级 含义 存储形式 存储引擎
Account 账户/租户,顶层多租户隔离机制 元数据 + 容器列表 SQLite 数据库
Container 容器,用户自定义的"桶",类似文件夹概念 元数据 + 对象列表 SQLite 数据库
Object 对象,数据体 + 自定义元数据 二进制文件 + xattr XFS 文件系统

数据模型关键特性 🔑

对象名称 Flat Namespace:
  ┌─────────────────────────────────────┐
  │  /v1/AUTH_project/container/obj     │
  │      ↕          ↕        ↕          │
  │    Account    Container  Object     │
  │                                     │
  │  对象名称中的 '/' 仅是名字的一部分:    │
  │  container/photos/2026/01/photo.jpg │
  │          ↕ 无真实目录层级 ↕           │
  └─────────────────────────────────────┘
  • Flat Namespace: 对象名支持 / 字符模拟目录层级,但无真正目录树结构
  • 单对象限制: 最大 5GB,超出需使用 SLO(静态大对象)/ DLO(动态大对象)分段上传
  • 元数据存储: 对象元数据存储在文件系统的 **xattr(扩展属性)**中,最大 4KB
  • 多租户隔离: 每个账户独立 namespace,AUTH_<project_id> 为默认账户前缀

三种实体各自拥有独立 Ring 映射

account.ring.gz    →  Account Server 集群映射
container.ring.gz  →  Container Server 集群映射
object.ring.gz     →  Object Server 集群映射

三、核心组件深度解析 🧩

1️⃣ Proxy Server — 请求入口网关

Proxy Server 是 Swift 对外的唯一入口,所有客户端请求必经此处。

Proxy Server 请求处理流水线:

1. 接收 HTTP 请求 (PUT / GET / DELETE / HEAD)
2. Keystone Token 鉴权验证
3. 解析路径 → Account/Container/Object
4. 查询对应 Ring 获取目标节点列表
5. 并发转发请求到所有副本节点
6. 等待 Quorum(W 个写成功 / R 个读成功)
7. 聚合响应返回客户端

特性:
  ├── 流式传输:对象数据流式通过,不缓冲到磁盘
  ├── 无状态:无本地状态,可任意横向扩展
  ├── Handoff 支持:主节点失败自动路由到 Handoff 节点
  └── 存储策略感知:2.x+ 支持多 Ring 策略路由

Proxy Server 中间件链:

WSGI Pipeline 中的中间件(按顺序执行):
  ├── healthcheck        → 健康检查端点
  ├── keystoneauth       → Token 鉴权
  ├── proxy-logging      → 访问日志
  ├── bulk              → 批量操作
  ├── tempurl            → 临时 URL
  ├── ratelimit          → 请求限速
  └── proxy-server       → 核心代理服务

2️⃣ Account / Container / Object Server — 存储节点三驾马车

Account Server:

职责:
  └── 管理账户元数据(容器列表 + 统计信息)
       ├── 使用 SQLite 存储
       ├── 记录各容器对象数量和总字节数
       └── 响应 HEAD 请求返回统计信息

Container Server:

职责:
  └── 管理容器元数据(对象列表 + 统计信息)
       ├── 使用 SQLite 存储
       ├── 维护对象列表(按名称排序)
       ├── 记录对象计数和总字节数
       └── 支持容器 ACL 访问控制

Object Server:

职责:
  └── 对象数据存储与检索
       ├── 以文件形式存储在 XFS 文件系统
       ├── 元数据存储在文件 xattr(扩展属性)
       ├── 基于时间戳的版本管理(Last-Write-Wins)
       ├── 墓碑文件(.ts)标记删除
       └── 支持对象分段上传的合并与读取

时间戳文件:
  ├── {TIMESTAMP}.DATA  → 对象数据文件
  ├── {TIMESTAMP}.META  → 元数据更新文件
  └── {TIMESTAMP}.TS    → 墓碑(0字节删除标记)

3️⃣ Replicator — 副本一致性守护者 🔄

Replicator 负责检测并修复副本不一致,采用 Push 推送模式

Replicator 工作循环:

  ┌─────────────────────────────────────┐
  │ 周期扫描本地所有分区文件              │
  │                                      │
  │ 对每个文件:                          │
  │  1. 查询 Ring 获取该分区的所有副本节点  │
  │  2. 通过 rsync 与远端节点比对          │
  │  3. 若本地文件更新 → push 到远端       │
  │  4. 若远端文件更新 → 本地会被覆盖       │
  │  5. 若本地有墓碑 → push 墓碑到远端      │
  │                                      │
  │ 同步对象:
  │  ├── rsync + hash 比对(对象文件)     │
  │  └── HTTP 或 rsync(SQLite 数据库)    │
  └─────────────────────────────────────┘

关键特性:

  • Push 模式的理由: Object Server 只读写入的文件,不主动拉取,Replicator 作为 Push 端主动同步
  • 数据库同步: 记录差异小于 1% 时使用 SQLite 差量同步,否则全量传输
  • 同步范围: 对象文件、容器数据库、账户数据库

4️⃣ Updater — 异步更新队列 ⏰

当高负载或节点故障导致容器 / 账户更新失败时,Updater 将更新任务序列化到本地队列异步处理:

处理流程:
  PUT 对象 → Proxy Server
       │
       ├── Object Server 写入成功 ✅
       │
       └── Container Server 更新失败 ❌(高负载/temporary unavailable)
                │
                ▼
          写入本地 async_pending 队列
                │
                ▼
           Updater 周期性重试
                │
                ▼
          容器列表最终更新 ✅

这就是最终一致性的主要来源:容器对象列表可能短暂滞后,Updater 保证最终收敛。


5️⃣ Auditor — 完整性审计 🔍

周期性扫描:
  ├── 对象审计: 读取文件内容,校验 xattr 元数据一致性
  ├── 容器审计: 校验 SQLite 数据库完整性
  └── 账户审计: 校验 SQLite 数据库完整性

发现问题:
  └── 将损坏文件移动到 /srv/node/{DEVICE}/quarantined/
       ├── 隔离文件不自动删除
       ├── Replicator 检测到缺失后从副本同步恢复
       └── 运维人员可分析隔离区的损坏文件

四、一致性哈希与 Ring 🎯

Ring — 最核心的数据结构

Ring 是 Swift 的灵魂,记录逻辑路径 → 物理位置的映射关系。

Ring 数据结构:

┌─────────────────────────────────────────┐
│              Ring 对象                   │
├─────────────────────────────────────────┤
│  devs: [                                 │
│    {id:0, zone:1, weight:100,           │
│     ip:"10.0.0.1", port:6200,           │
│     device:"sdb1"},                     │
│    {id:1, zone:2, weight:200, ...},     │
│    ...                                   │
│  ]                                       │
├─────────────────────────────────────────┤
│  _replica2part2dev_id: [                 │
│    [dev_id_A, dev_id_B, dev_id_C],  ← Partition 0 的 3 个副本
│    [dev_id_D, dev_id_E, dev_id_F],  ← Partition 1 的 3 个副本
│    ...                                   │
│  ]                                       │
├─────────────────────────────────────────┤
│  part_shift: 4           ← 分区移位位数  │
│  replica_count: 3        ← 副本数       │
│  part_power: 10          ← 总分区数 2^10│
└─────────────────────────────────────────┘

物理隔离层级(故障域)

Region (地理区域: 数据中心)
   └── Zone (硬件隔离: 机架/交换机)
        └── Node (服务器节点)
             └── Device (磁盘设备)

Swift 原则:
  同一 Partition 的 Replica 必须分布在不同 Zone 内
  确保任意 Zone 故障不影响所有副本

数据路由流程 🧭

对象路径: /v1/AUTH_acc/container/object
                  │
             计算 MD5 哈希
                  │
             取前 4 字节
                  │
        右移 part_shift 位
                  │
   ┌──────────────┴──────────────┐
   │     得到分区编号 Partition   │
   └──────────────┬──────────────┘
                  │
     _replica2part2dev_id[Partition]
                  │
   ┌──────────────┼──────────────┐
   ▼              ▼              ▼
 设备 A (Zone 1) 设备 B (Zone 2) 设备 C (Zone 3)
  ── 主副本 ──  ── 副本 ──  ── 副本 ──
                  │
   Proxy Server 将请求同时发往所有副本节点

虚拟节点(Partition)机制

物理节点与虚拟节点的关系:

   ┌─────────────────────────────────────────┐
   │  总分区数 = 2^part_power               │
   │                                        │
   │  每个物理节点包含 N 个虚拟分区:           │
   │    分区数 ≈ (节点权重 / 总权重) × 总分区数 │
   │                                        │
   │  增减节点的影响:                         │
   │    仅重新分配受影响的分区                │
   │    移动比例 ≈ 1 / 总节点数              │
   │    100 节点集群中仅移动 1% 数据          │
   └─────────────────────────────────────────┘

优势:
  ├── 数据自动均匀分布
  ├── 节点增减仅影响少数分区
  └── 权重支持异构磁盘(如 2TB 权重=100, 4TB 权重=200)

Ring 构建与维护命令 🔧

# 1. 创建 Ring
swift-ring-builder OBJECT_BUILDER create PART_POWER REPLICAS MIN_PART_HOURS

# 参数:
#   PART_POWER     分区幂次,总分区数 = 2^PART_POWER(推荐 10~15)
#   REPLICAS       副本数(默认 3)
#   MIN_PART_HOURS 分区最小移动间隔(小时),防止 Rebalance 抖动


# 2. 添加设备
swift-ring-builder OBJECT_BUILDER add Z{ZONE}-{IP}:{PORT}/{DEVICE} WEIGHT

# 参数:
#   Z{ZONE}    故障域编号(如 z1, z2, z3)
#   {IP}       存储节点 IP
#   {PORT}     Object Server 端口(默认 6200)
#   {DEVICE}   磁盘设备名称(如 sdb1)
#   WEIGHT     设备权重(按磁盘容量比例)


# 3. 重新平衡(自动最小化数据移动)
swift-ring-builder OBJECT_BUILDER rebalance

# 4. 查看 Ring 信息
swift-ring-builder OBJECT_BUILDER


# 完整示例(3 节点,3 Zone,每节点 2 块磁盘):
swift-ring-builder object.builder create 12 3 1
swift-ring-builder object.builder add z1-10.0.0.1:6200/sdb1 100
swift-ring-builder object.builder add z1-10.0.0.1:6200/sdc1 100
swift-ring-builder object.builder add z2-10.0.0.2:6200/sdb1 100
swift-ring-builder object.builder add z2-10.0.0.2:6200/sdc1 100
swift-ring-builder object.builder add z3-10.0.0.3:6200/sdb1 100
swift-ring-builder object.builder add z3-10.0.0.3:6200/sdc1 100
swift-ring-builder object.builder rebalance

五、数据冗余与一致性模型 🛡️

Quorum 仲裁协议

Swift 采用 Quorum 仲裁实现最终一致性:

写入流程:
  PUT /v1/AUTH_acc/container/object
       │
       ├── 查询 Object Ring → 3 个目标节点(Zone 1, 2, 3)
       │
       ├── Proxy 并发向 3 个 Object Server 发送数据
       │
       ├── 等待至少 W 个成功响应(W=2)
       │
       └── 返回 201 Created 给客户端
                │
         ┌──────┴──────┐
         │             │
      ✅ 成功        ❌ < 2 个成功
                   └── 写入失败,返回 503

读取流程:
  GET /v1/AUTH_acc/container/object
       │
       ├── 查询 Object Ring → 3 个目标节点
       │
       ├── 向 3 个节点发送 GET 请求
       │
       ├── 默认: 等待 1 个成功即返回(R=1,弱一致性)
       │
       │  或使用 X-Newest: true:
       │  └── 对比多个副本的时间戳,返回最新版本(R=2,强一致性)
       │
       └── 返回对象数据 + 元数据
参数 Swift 默认值 说明
N 3 每个对象存储 3 个副本
W 2 写操作需 ≥2 个副本确认才算成功
R 1(可调至 2) 读操作 1 个副本成功即返回

一致性保证: R + W > N(保证读写副本集有交集,避免读取到过期数据)

模式 R W 一致性强度 性能影响
弱一致性(默认) 1 2 最终一致 最高性能
强一致读 2 2 接近强一致 读性能下降
强一致写 1 3 写后即可读 写性能下降

数据冗余保障机制 🏗️

多副本冗余分布:

  ┌── Region 1 ──────────────────────┐
  │  ┌── Zone 1 ──┐ ┌── Zone 2 ──┐  │
  │  │  Node 1     │ │  Node 2     │  │
  │  │  ┌──┐ ┌──┐│ │ ┌──┐ ┌──┐│  │
  │  │  │R1│ │D1││ │ │R2│ │D2││  │
  │  │  └──┘ └──┘│ │ └──┘ └──┘│  │
  │  └───────────┘ └───────────┘  │
  └───────────────────────────────┘
         │
  ┌── Region 2 ──────────────────────┐
  │  ┌── Zone 3 ──┐                  │
  │  │  Node 3     │                  │
  │  │  ┌──┐ ┌──┐│                  │
  │  │  │R3│ │D3││                  │
  │  │  └──┘ └──┘│                  │
  │  └───────────┘                   │
  └──────────────────────────────────┘

  R = 副本 (Replica), D = 非副本数据
  N=3, 跨 Region 分布: Region 1 放 2 副本, Region 2 放 1 副本

数据冗余措施一览:

机制 工作方式 触发条件
多副本冗余 默认 3 副本,跨 Zone 分布 数据写入时自动创建
Handoff 节点 主节点不可用时写入临时 Handoff 节点 主节点故障/离线
Replicator Push 模式 rsync 同步副本差异 周期性后台运行
Updater 序列化失败更新至 async_pending 队列 容器/账户更新失败
Auditor 扫描完整性,隔离损坏文件 周期性后台运行
Tombstone 创建 .ts 空文件标记删除 DELETE 请求触发
跨 Region 副本分布在不同数据中心 Ring 配置多个 Region

Handoff 节点故障转移流程:

主节点 A 不可用
     │
     ▼
Proxy 尝试写入 → 超时/连接失败
     │
     ▼
查询 Ring 中的 Handoff 节点列表
     │
     ▼
写入 Handoff 节点 H 成功 ✅
     │
     ▼
主节点 A 恢复
     │
     ▼
Replicator 检测到 H 上有 A 的数据
     │
     ▼
Replicator 将数据从 H 复制回 A
     │
     ▼
从 H 删除临时数据,恢复正常拓扑

六、数据存储结构详解 📁

磁盘目录结构

/srv/node/{DEVICE}/
├── accounts/                    账户数据库
│   └── {PARTITION}/
│       └── {SUFFIX}/
│           └── {HASH}/
│               └── {ACCOUNT}.db  ← SQLite 数据库文件
│
├── containers/                  容器数据库
│   └── {PARTITION}/
│       └── {SUFFIX}/
│           └── {HASH}/
│               └── {CONTAINER}.db  ← SQLite 数据库文件
│
├── objects/                     对象数据
│   └── {PARTITION}/
│       └── {SUFFIX}/
│           └── {HASH}/
│               ├── {TIMESTAMP}.DATA   对象数据文件
│               ├── {TIMESTAMP}.META   元数据更新文件
│               └── {TIMESTAMP}.TS     墓碑文件(0字节)
│
├── async_pending/               异步待更新队列
│
├── quarantined/                 隔离目录(损坏数据)
│
└── tmp/                         临时写入目录

说明:
  {PARTITION}:   Ring 计算出的分区号
  {SUFFIX}:      Hash 值的后 3 位(目录散列,避免单目录文件过多)
  {HASH}:        MD5 哈希值
  {TIMESTAMP}:   Unix 时间戳(精确到微秒)

文件系统要求

属性 要求
类型 XFS(推荐,支持 xattr)
atime 关闭(noatime 挂载)
inode 足够大(每个对象至少 1 个 inode)
xattr 必须支持(存储对象元数据,默认 4KB 上限)

xattr 存储内容:

user.swift.metadata:
  ├── name              对象名称
  ├── content-length    对象大小
  ├── content-type      MIME 类型
  ├── etag              MD5 校验值
  ├── x-object-meta-*   自定义元数据
  └── timestamp         写入时间戳

七、存储策略(Storage Policies, Swift 2.0+)🎯

Swift 2.x 版本引入存储策略机制,支持在 Container 级别指定不同策略:

# 查看可用策略
swift --os-storage-url <URL> stat

# 创建带策略的容器
openstack container create --STORAGE-POLICY gold-container gold-bucket

# 列出存储策略
swift-list-policies

策略类型

策略 副本数 适用场景
3 副本(默认) 3 关键数据、生产环境
2 副本 2 非关键数据、成本敏感场景
EC(纠删码) 数据分片 + 校验 大容量归档,同一冗余度下存储效率更高

EC vs 副本对比:

3 副本方案:
  数据量: 100GB  实际占用: 300GB  可用率: 33%

EC (6+3) 方案:
  数据量: 100GB  实际占用: 150GB  可用率: 66%
  承受故障: 任意 3 块磁盘

多 Ring 配置

# /etc/swift/swift.conf
[storage-policy:0]
name = gold
policy_type = replication
default = yes
aliases = gold,3x

[storage-policy:1]
name = silver
policy_type = replication
aliases = silver,2x

[storage-policy:2]
name = archive
policy_type = erasure_coding
ec_type = liberasurecode_rs_vand
ec_num_data_fragments = 6
ec_num_parity_fragments = 3
ec_object_segment_size = 1048576

八、数据流详解 🌊

PUT 写入完整流程

客户端:
  PUT /v1/AUTH_acc/container/object
  └── Content-Length, Content-Type, ETag, X-Auth-Token

Proxy Server:
  ① 验证 Token(Keystone)
  ② 解析路径 → Account=acc, Container=container, Object=object
  ③ 查询 Object.Ring → 分区 1324 → [设备A Zone1, 设备B Zone2, 设备C Zone3]
  ④ 并发流式写入 3 个 Object Server(不缓冲)

Object Server (3 个节点并行):
  ① 接收数据流
  ② 写入 tmp/ 临时目录
  ③ 校验 ETag(MD5)一致性
  ④ 写入 XFS 持久化
  ⑤ 将元数据写入 xattr
  ⑥ 重命名到 objects/{PARTITION}/{SUFFIX}/{HASH}/{TIMESTAMP}.DATA

Proxy Server:
  ⑦ 等待 W=2 个节点成功 ✅
  ⑧ 返回 201 Created

后台 (异步):
  ⑨ 异步更新 Container 对象列表(若失败则 Updater 排队重试)

GET 读取完整流程

客户端:
  GET /v1/AUTH_acc/container/object
  └── X-Auth-Token

Proxy Server:
  ① 验证 Token(Keystone)
  ② 查询 Object.Ring → 分区 1324 → [设备A Zone1, 设备B Zone2, 设备C Zone3]
  ③ 并发向 3 个 Object Server 发起 GET

Object Server (3 个节点):
  ④ 查找 {PARTITION}/{SUFFIX}/{HASH}/{TIMESTAMP}.DATA
  ⑤ 验证 xattr 元数据完整性
  ⑥ 流式返回数据

Proxy Server:
  ⑦ 默认: 取最快返回的一个(R=1)
     或 X-Newest: 取时间戳最新的一个(R=2)
  ⑧ 流式传输给客户端(不缓冲到磁盘)

DELETE 删除流程

客户端:
  DELETE /v1/AUTH_acc/container/object

Proxy Server:
  ① 验证 Token → 查询 Ring → 路由到 3 个副本节点
  ② 并发发送 DELETE 请求

Object Server (3 个节点):
  ③ 不直接删除 .data 文件
  ④ 创建 {TIMESTAMP}.TS 墓碑文件(0字节)
  ⑤ 墓碑的 .ts 时间戳 > .data 文件时间戳

后续:
  ⑥ Replicator 将墓碑传播到所有副本
  ⑦ Auditor 日后扫描时清理旧 .data 文件
  ⑧ Container 对象列表中移除该对象

九、API 与常用操作 📋

RESTful API 端点

方法 URL 功能
GET /v1/{ACCOUNT} 获取账户信息、容器列表
GET /v1/{ACCOUNT}/{CONTAINER} 获取容器内对象列表
PUT /v1/{ACCOUNT}/{CONTAINER}/{OBJECT} 上传对象
GET /v1/{ACCOUNT}/{CONTAINER}/{OBJECT} 下载对象
DELETE /v1/{ACCOUNT}/{CONTAINER}/{OBJECT} 删除对象
HEAD /v1/{ACCOUNT}/{CONTAINER}/{OBJECT} 获取对象元数据
POST /v1/{ACCOUNT}/{CONTAINER}/{OBJECT} 更新对象元数据

常用 Swift CLI 命令

# ─── 账户操作 ───

# 查看账户信息
openstack container list
swift list

# ─── 容器操作 ───

# 创建容器
openstack container create <CONTAINER_NAME>
swift post <CONTAINER_NAME>

# 列出容器内容
openstack container show <CONTAINER_NAME>
swift list <CONTAINER_NAME>

# 删除容器(需先清空对象)
openstack container delete <CONTAINER_NAME>

# ─── 对象操作 ───

# 上传对象
openstack object create <CONTAINER_NAME> <LOCAL_FILE>
swift upload <CONTAINER_NAME> <LOCAL_FILE>
#                      ├── --OBJECT-NAME 指定远程对象名
#                      ├── --SEGMENT-SIZE 大对象分段大小(字节)
#                      ├── --SEGMENT-CONTAINER 分段存储容器
#                      └── --CHANGE-DIR 保持目录结构

# 下载对象
openstack object save <CONTAINER_NAME> <OBJECT_NAME>
swift download <CONTAINER_NAME> <OBJECT_NAME>

# 列出对象
openstack object list <CONTAINER_NAME>
swift list <CONTAINER_NAME>

# 删除对象
openstack object delete <CONTAINER_NAME> <OBJECT_NAME>
swift delete <CONTAINER_NAME> <OBJECT_NAME>

# 查看对象详情
openstack object show <CONTAINER_NAME> <OBJECT_NAME>

# 获取临时 URL(限时访问)
swift tempurl GET 3600 /v1/AUTH_acc/container/object <SECRET_KEY>

# ─── 大对象分段上传 ───

# 动态大对象 (DLO): 自动分段
swift upload --SEGMENT-SIZE 1073741824 --SEGMENT-CONTAINER seg-container \
  <CONTAINER_NAME> <LARGE_FILE>
#                      └── --SEGMENT-SIZE 分段大小(本例 1GB)

# 静态大对象 (SLO): 手动分段 + manifest
swift upload --USE-SLO --SEGMENT-SIZE 1073741824 \
  --SEGMENT-CONTAINER seg-container <CONTAINER_NAME> <LARGE_FILE>

TempURL(临时 URL 访问)

# 1. 设置密钥
swift post -m temp-url-key:SECRET_KEY

# 2. 生成临时 URL
swift tempurl GET 3600 /v1/AUTH_acc/container/object SECRET_KEY
#                      ├── GET/PUT  HTTP 方法
#                      ├── 3600    有效期(秒)
#                      └── 返回完整 URL(含签名参数)

# 3. 直接通过 URL 访问(无需 Token)
curl -X GET "<TEMP_URL>"

# 用途: CDN 回源、文件分享、第三方下载

ACL(访问控制列表)

# 设置容器 ACL 允许特定用户读
swift post <CONTAINER> -r <USER_ID>
#                      ├── -r 读权限
#                      └── -w 写权限

# 允许所有用户读(公开容器)
swift post <CONTAINER> -r ".r:*,.rlistings"
#                      ├── .r:* 允许所有 Referer 读取对象
#                      └── .rlistings 允许列出容器内容

# 移除 ACL
swift post <CONTAINER> -r ""

十、生产部署最佳实践 ✅

实践 说明
最小 3 Zone 部署 每个 Zone 独立机架/电源/交换机,防止单机架故障导致数据丢失
XFS 文件系统 XFS 的 xattr 支持是 Swift 元数据存储的基石,挂载时用 noatime,nodiratime
权重平衡 按磁盘实际容量设置 WEIGHT,确保数据均匀分布
Part Power 选择 推荐 10~15(总分区数 1024~32768),节点越多值越大
专用存储网络 使用独立 VLAN/网卡承载 Replicator 同步流量,不与公共网络争用
Memcached 集群 至少 2 节点 Memcached 缓存 Token 和查询结果,不缓存对象数据
Proxy 水平扩展 Proxy Server 无状态,前置负载均衡器(HAProxy)即可无限扩展
Replicator 并发控制 据节点数调整并发数,防止 rsync 风暴导致 IO 过载
定期审计巡检 监控 quarantined 目录的隔离文件量,早期发现磁盘故障
监控关键指标 对象计数、成功/失败请求比、异步队列深度、Replicator 队列长度

规模建议

规模 节点数 Zone 数 Part Power 副本
测试/开发 3 3 8 2
中小生产 6~20 3~4 10~12 3
大规模生产 20~100+ 4~8 12~15 3 或 EC
跨 Region 灾备 50+ 多 Region 14~15 3(跨 Region 分布)

十一、应用场景 🎯

场景 典型负载 Swift 优势
备份与归档 📋 数据库备份、日志存档、合规文件 普通硬件低成本、PB 级线性扩展、跨 Zone 冗余安全
图片/视频存储 🖼️ 静态资源托管、CDN 源站、监控录像 RESTful API 流式直读、CDN 回源(TempURL)、分段上传支持
虚拟机镜像 🖥️ Glance 后端镜像存储 无限容量、大对象支持、高并发读取
非结构化数据 📄 文档存储、邮件归档、日志分析 Flat Namespace 无层级限制、多租户 ACL 隔离
云存储服务 ☁️ 企业网盘、文件共享(Drogon/DavGate) S3 兼容网关、Token 认证、Quota 管理

与其他存储方案对比:

特性 Swift(对象) Ceph RBD(块) NFS(文件)
访问协议 HTTP REST iSCSI / librbd NFS v3/v4
挂载方式 HTTP API 块设备挂载 文件系统挂载
典型延迟 毫秒级(HTTP) 微秒级(本地) 微秒级
伸缩性 ✅ PB 级水平扩展 ✅ PB 级 ⚠️ 有限
随机读写 ❌ 不适合 ✅ 块级随机访问 ⚠️ 中等
适用场景 静态内容、备份 数据库、云硬盘 共享目录、代码
数据冗余 多副本/EC 多副本/EC 依赖底层存储

十二、版本演进趋势 🚀

版本 核心变化
2010 Rackspace 贡献给 OpenStack
Grizzly Swift 成为 OpenStack 正式核心组件
Havana 引入 Region 支持,跨数据中心复制
Icehouse 存储策略(Storage Policies)预览
Juno 存储策略正式发布,支持多 Ring
Kilo EC(纠删码)策略引入
Liberty EC 策略稳定,性能优化
Mitaka 全局集群扩展,跨 Region 复制增强
Newton 对象版本化支持
Pike SLO(静态大对象)优化
Queens 性能与稳定性持续提升
Stein EC 重建优化
Train 加密与安全增强
Wallaby 磁盘使用效率优化
Xena 弃用旧版特性
2024.2 Dalmatian 增强的 EC 策略与运维工具
2025.1 Epoxy Python 3.x 兼容性加固
2026.1 Gazpacho 性能持续优化,磁盘利用率提升

💡 技术解析

  • 术语: Consistent Hashing(一致性哈希) — 分布式系统中控制数据分布的核心算法。增删节点时仅需重新映射 1/N 的数据(N 为节点数),而非全量重新哈希。Swift 通过引入虚拟节点(Partition)进一步提高了平衡性和单调性。

  • 术语: Ring — Swift 最核心的数据结构,存储逻辑路径(Account/Container/Object 名)到物理设备(磁盘 IP+ 端口)的映射。各实体类型有独立 Ring,通过 _replica2part2dev_id 二维数组和 part_shift 实现 O(1) 查找性能。

  • 术语: Quorum(仲裁) — 分布式系统中通过多数派投票确保数据一致性的协议。Swift 的 N=3, W=2, R=1 配置下,读写副本集必然存在交集,保证至少有一个副本包含最新数据。条件 R+W > N 是 Quorum 的核心约束。

  • 术语: Partition(虚拟节点) — 一致性哈希中引入的虚拟节点概念,是哈希空间中的固定粒度分区。每个物理设备承载多个 Partition,通过增加 Partition 数量(默认物理节点数 × 100)使数据分布更均匀,节点变动时仅影响 1% 的数据项。

  • 术语: Handoff(故障转移节点) — 当主副本节点不可用时,Proxy Server 将数据写入临时 Handoff 节点的机制。Handoff 节点是 Ring 中的次优选择,待主节点恢复后由 Replicator 将数据同步回主节点。

  • 术语: Tombstone(墓碑) — Swift 的删除标记文件(.ts),0 字节。删除对象时不直接删除数据文件,而是创建时间戳更新的墓碑文件。Replicator 将墓碑传播到所有副本,Auditor 后续清理旧数据文件。这种设计确保删除操作在最终一致性模型下被可靠传播。

  • 术语: xattr(扩展属性) — Linux 文件系统的扩展属性机制(Extended Attributes),Swift 用它存储对象的元数据(名称、大小、ETag、Content-Type、自定义元数据等)。要求文件系统支持 xattr(XFS 原生支持,ext4 需 user_xattr 挂载选项)。

  • 术语: Zone(故障域) — Swift 中最小物理隔离单元,一般对应一个独立机架。同 Zone 内可有一台或多台服务器。Ring 构建时保证同一 Partition 的 Replica 分布在不同的 Zone 中,确保任意单个机架故障不影响数据完整性。

  • 术语: SLO/DLO(静态 / 动态大对象) — 支持超 5GB 对象的分段上传机制。DLO(动态大对象)使用 manifest 文件动态拼接分段,分段可独立管理。SLO(静态大对象)在 manifest 中固化分段列表(含 ETag),完整性校验更严格。

  • 命令: swift-ring-builder — Swift 的 Ring 构建与管理工具。create 指定分区幂次 / 副本数 / 最小移动间隔;add 添加存储设备并指定 Zone/ 权重;rebalance 根据当前设备列表自动计算分区分配方案并最小化数据移动量。生成的 .ring.gz 文件需要分发到所有集群节点。

  • 命令: swift upload — 上传对象到 Swift 容器,--OBJECT-NAME 自定义远程对象名,--SEGMENT-SIZE 设置分段大小(大对象自动分段),--CHANGE-DIR 上传时保持本地目录结构。自动基于文件内容计算 ETag(MD5)供完整性校验。

  • 命令: swift tempurl — 生成带签名的临时 URL,允许限时免认证访问。GET/PUT 指定 HTTP 方法,`` 指定有效期(秒)。用于 CDN 回源、文件分享、第三方下载等场景。安全性依赖密钥保密性。


0
上一篇 OpenStack Glance镜像服务详解
下一篇 OpenStack Heat(编排)详解