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)。
2.3 键(Key)的领域语义与目录模拟
对象存储的键(Key)是一个扁平命名空间,但通过前缀匹配和分隔符(通常为 /)可以模拟出目录层次结构。这种设计在领域建模中非常重要:
- 扁平结构:所有对象都在桶的同一层级,没有真正的目录实体。
- 前缀扫描:通过
ListObjects操作和prefix参数,可以模拟“进入子目录”的效果。 - 分隔符分组:使用
delimiter=/可以将对象按“目录”分组返回,提升检索效率。
示例: 桶内存在以下键:
使用
images/2024/photo1.jpgimages/2024/photo2.jpgimages/2023/photo3.jpgdocs/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)的生成策略
全局唯一标识符是对象存储实现去重和跨区域复制的基础。常见的生成策略包括:
- UUID v4(随机):基于随机数生成,冲突概率极低,适合分布式环境。
- UUID v5(基于名称):基于桶名 + 键 + 时间戳的 SHA-1 哈希,相同内容生成相同 UID,天然支持去重。
- 雪花算法(Snowflake):结合时间戳、机器 ID 和序列号,生成有序且唯一的 64 位整数。
- 内容寻址(Content-Addressable):基于数据载荷的哈希值(如 SHA-256)作为 UID,实现“写入即去重”。
下图对比了两种主流 UID 生成策略的流程差异:
2.6 核心概念在领域模型中的位置
在后续的领域建模中,这五个核心概念将分别映射到不同的领域实体(Entity)和值对象(Value Object):
- 桶(Bucket):领域实体,拥有全局唯一标识(桶名称),是聚合根。
- 对象(Object):领域实体,拥有全局唯一标识(UID),生命周期由桶管理。
- 键(Key):值对象,在桶内唯一,用于对象定位。
- 元数据(Metadata):值对象,作为对象的属性集合,可独立更新。
- 全局唯一标识符(UID):值对象,作为对象的身份标识,不可变。
建模要点: 将 Key 和 UID 都建模为值对象,是因为它们没有独立的生命周期,完全依附于对象实体。桶作为聚合根,负责维护“桶名 + 键”到“对象 UID”的映射关系,这是后续服务边界划分的核心依据。