2. 核心概念:对象(Object)、桶(Bucket)、键(Key)、元数据(Metadata)、全局唯一标识符(UUID/UID)

对象存储的领域模型围绕五个核心概念构建:对象、桶、键、元数据和全局唯一标识符。这五个概念构成了对象存储的“词汇表”,也是后续进行领域建模和服务边界划分的基础。理解它们之间的静态关系与动态交互,是掌握对象存储架构的第一步。

2.1 核心概念定义与职责

下表从领域驱动设计的角度,定义了每个核心概念的职责、边界和典型属性:

概念 领域职责 关键属性 类比(文件系统)
对象(Object) 数据存储的原子单元,包含数据本体及其描述信息。 数据载荷(Data Payload)、元数据引用、唯一标识符 文件内容 + 文件属性
桶(Bucket) 对象的逻辑容器,提供命名空间隔离、访问策略和计费边界。 桶名称、区域(Region)、存储类别、ACL 顶级目录(不可嵌套)
键(Key) 对象在桶内的唯一逻辑名称,用于定位和检索对象。 字符串(支持前缀/分隔符模拟目录) 文件路径(如 /dir/file.txt)
元数据(Metadata) 描述对象属性的结构化数据,分为系统元数据和用户自定义元数据。 键值对(Key-Value)、HTTP 头兼容 文件 inode 信息 + 扩展属性
全局唯一标识符(UUID/UID) 对象的全局唯一身份标识,用于去重、数据校验和跨系统引用。 128 位整数(UUID 格式)、不可变 inode 编号(全局唯一)
领域建模提示: 在对象存储领域,桶是一个聚合根(Aggregate Root),它负责管理其内部所有对象的生命周期和访问权限。对象不能脱离桶而独立存在,桶的删除通常意味着其内部所有对象的逻辑删除或回收。

2.2 核心概念关系模型

下图展示了五个核心概念之间的静态结构关系。桶作为顶层容器,通过键(Key)唯一映射到对象;对象内部封装了数据载荷、元数据和全局唯一标识符(UID)。

对象存储核心概念关系模型 对象存储核心概念关系模型 桶(Bucket) 逻辑容器 / 命名空间 键(Key) 逻辑名称 / 定位符 对象(Object) 数据原子单元 1:N 映射 1:1 映射 数据载荷(Data) 元数据(Metadata) 全局唯一标识符(UID) 关键约束: • 桶名称全局唯一(同一区域),键在桶内唯一。 • 对象 UID 全局唯一,由系统自动生成,不可修改。 • 元数据与数据载荷分离存储,但逻辑上属于同一对象。

2.3 键(Key)的领域语义与目录模拟

对象存储的键(Key)是一个扁平命名空间,但通过前缀匹配和分隔符(通常为 /)可以模拟出目录层次结构。这种设计在领域建模中非常重要:

  • 扁平结构:所有对象都在桶的同一层级,没有真正的目录实体。
  • 前缀扫描:通过 ListObjects 操作和 prefix 参数,可以模拟“进入子目录”的效果。
  • 分隔符分组:使用 delimiter=/ 可以将对象按“目录”分组返回,提升检索效率。
示例: 桶内存在以下键:
images/2024/photo1.jpg
images/2024/photo2.jpg
images/2023/photo3.jpg
docs/report.pdf
使用 prefix=images/2024/ 和 delimiter=/ 可以只返回 images/2024/ 下的对象,而不会返回 images/2023/ 或 docs/ 下的内容。

2.4 元数据(Metadata)的领域分类

元数据是对象存储区别于块存储和文件存储的关键特征。从领域建模角度,元数据可分为三类:

分类 示例 可变性 领域用途
系统元数据 Content-Length、ETag、Last-Modified、Storage-Class 部分只读(如 ETag) 数据完整性校验、生命周期管理、访问控制
用户自定义元数据 x-amz-meta-project、x-amz-meta-owner 可读写 业务标签、自定义分类、搜索索引
保留元数据 x-amz-acl、x-amz-server-side-encryption 特定操作可写 访问策略、加密配置、合规标记
设计陷阱: 用户自定义元数据的键值对大小通常有严格限制(如 AWS S3 限制为 2KB)。在领域建模时,不应将元数据作为大数据存储的扩展,而应将其视为索引属性。如果需要存储大量业务属性,建议使用外部数据库并通过对象 UID 关联。

2.5 全局唯一标识符(UUID/UID)的生成策略

全局唯一标识符是对象存储实现去重和跨区域复制的基础。常见的生成策略包括:

  1. UUID v4(随机):基于随机数生成,冲突概率极低,适合分布式环境。
  2. UUID v5(基于名称):基于桶名 + 键 + 时间戳的 SHA-1 哈希,相同内容生成相同 UID,天然支持去重。
  3. 雪花算法(Snowflake):结合时间戳、机器 ID 和序列号,生成有序且唯一的 64 位整数。
  4. 内容寻址(Content-Addressable):基于数据载荷的哈希值(如 SHA-256)作为 UID,实现“写入即去重”。

下图对比了两种主流 UID 生成策略的流程差异:

UID 生成策略对比:UUID v4 vs 内容寻址 UID 生成策略对比:UUID v4 vs 内容寻址 UUID v4(随机生成) 输入:无(纯随机数) 输出:128 位随机 UID 特点:冲突概率极低,无序,适合通用场景 内容寻址(Content-Addressable) 输入:数据载荷(Data Payload) 输出:SHA-256 哈希值作为 UID 特点:相同内容生成相同 UID,天然去重 领域决策:去重需求高时优先选择内容寻址;需要高性能随机写入时优先选择 UUID v4 或雪花算法。

2.6 核心概念在领域模型中的位置

在后续的领域建模中,这五个核心概念将分别映射到不同的领域实体(Entity)和值对象(Value Object):

  • 桶(Bucket):领域实体,拥有全局唯一标识(桶名称),是聚合根。
  • 对象(Object):领域实体,拥有全局唯一标识(UID),生命周期由桶管理。
  • 键(Key):值对象,在桶内唯一,用于对象定位。
  • 元数据(Metadata):值对象,作为对象的属性集合,可独立更新。
  • 全局唯一标识符(UID):值对象,作为对象的身份标识,不可变。
建模要点: 将 Key 和 UID 都建模为值对象,是因为它们没有独立的生命周期,完全依附于对象实体。桶作为聚合根,负责维护“桶名 + 键”到“对象 UID”的映射关系,这是后续服务边界划分的核心依据。