2、对象存储基础:S3协议、桶与对象、存储类与访问控制列表(ACL)
对象存储是现代云原生架构的基石,而 Amazon S3(Simple Storage Service)协议已成为对象存储的事实标准。PostgreSQL 集成对象存储网关(如 pg_parquet、pg_analytics、cstore_fdw 等)均以 S3 兼容 API 作为数据源接入层。理解 S3 协议的核心概念——桶、对象、存储类与 ACL——是优化查询性能与设计存储策略的前提。
2.1 S3 协议概述
S3 协议定义了一套基于 RESTful 的 HTTP/HTTPS 接口,用于对对象存储执行创建、读取、更新、删除(CRUD)操作。其核心设计原则包括:
- 扁平命名空间:所有数据以“桶(Bucket)+ 对象键(Object Key)”的二元结构寻址,无传统文件系统的目录层级。
- 最终一致性:部分操作(如覆盖写)在分布式环境下存在短暂不一致窗口,但大多数现代实现已提供读后写一致性。
- 原子性操作:单个 PUT 操作是原子的,但多部分上传(Multipart Upload)需要显式管理。
- 元数据扩展:每个对象可附带系统元数据(如 ETag、Content-Length)和用户自定义元数据(以
x-amz-meta-为前缀)。
2.2 桶(Bucket)与对象(Object)
桶是对象的容器,也是权限与存储策略的边界。对象是存储的基本单元,由数据、键和元数据组成。下表对比了桶与对象的关键属性:
| 维度 | 桶(Bucket) | 对象(Object) |
|---|---|---|
| 命名空间 | 全局唯一(所有 AWS 账户共享) | 桶内唯一(通过对象键区分) |
| 数量限制 | 每个账户默认 100 个(可申请提升) | 每个桶无数量上限 |
| 大小限制 | 无 | 单个对象最大 5TB(单次 PUT 最大 5GB) |
| 版本控制 | 桶级开关 | 每个对象可保留多个版本 |
| 生命周期 | 桶级策略 | 按前缀或标签自动转换存储类/过期删除 |
| 访问控制 | 桶策略(Bucket Policy)+ ACL | 对象 ACL + 桶策略继承 |
对象键(Object Key)通常使用 / 分隔符模拟目录结构,例如 logs/2025/04/01/access.log.gz。但需注意:S3 本身并无目录实体,/ 只是键名的一部分。PostgreSQL 网关在扫描对象时,可通过 Prefix 和 Delimiter 参数实现逻辑分区裁剪,减少扫描范围。
year=2025/month=04/day=01/),可让网关利用 S3 ListObjects 的 Prefix 参数跳过无关分区,显著提升查询性能。
2.3 存储类(Storage Class)
存储类定义了对象的持久性、可用性、访问延迟与成本。PostgreSQL 网关在查询低频存储类对象时,需注意首次访问延迟(冷启动)。以下是主流存储类的对比:
| 存储类 | 持久性 | 可用性 | 首字节延迟 | 最低存储时长 | 适用场景 |
|---|---|---|---|---|---|
| S3 Standard | 99.999999999% | 99.99% | 毫秒级 | 无 | 热数据、实时分析 |
| S3 Intelligent-Tiering | 99.999999999% | 99.99% | 毫秒级 | 30天 | 访问模式不确定 |
| S3 Standard-IA | 99.999999999% | 99.9% | 毫秒级 | 30天 | 低频访问但需快速读取 |
| S3 One Zone-IA | 99.999999999% | 99.5% | 毫秒级 | 30天 | 可重建的非关键数据 |
| S3 Glacier Instant Retrieval | 99.999999999% | 99.9% | 毫秒级 | 90天 | 归档但需即时访问 |
| S3 Glacier Flexible Retrieval | 99.999999999% | 99.99%(恢复后) | 1-5分钟(标准恢复) | 90天 | 长期归档,可接受分钟级延迟 |
| S3 Glacier Deep Archive | 99.999999999% | 99.99%(恢复后) | 12小时(标准恢复) | 180天 | 合规归档,极少访问 |
403 InvalidObjectState 错误。网关不会自动触发恢复操作,必须在查询前通过 POST /restore 接口手动恢复对象。建议将分析查询的目标数据至少放在 Standard-IA 或 Glacier Instant Retrieval 中。
2.4 访问控制列表(ACL)
ACL 是 S3 中一种传统的访问控制机制,用于管理桶和对象的读写权限。虽然 AWS 推荐使用更精细的 IAM 策略 和 桶策略,但 ACL 在跨账户共享和兼容旧系统时仍广泛使用。ACL 使用预定义的权限集合:
- READ:允许列出桶内对象(桶级)或读取对象数据及元数据(对象级)。
- WRITE:允许创建、覆盖、删除对象(仅桶级有效)。
- READ_ACP:允许读取 ACL。
- WRITE_ACP:允许修改 ACL。
- FULL_CONTROL:上述所有权限。
ACL 的授权对象分为两类:
| 授权对象 | URI 标识 | 典型用途 |
|---|---|---|
| 账户(Canonical User) | 用户 ID(如 a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6) |
授予特定 AWS 账户访问权限 |
| 预定义组 | http://acs.amazonaws.com/groups/global/AllUsers |
公开访问(匿名读/写) |
http://acs.amazonaws.com/groups/global/AuthenticatedUsers |
所有经过身份验证的 AWS 用户 | |
http://acs.amazonaws.com/groups/s3/LogDelivery |
仅用于 S3 服务器访问日志写入 |
s3:GetObject 和 s3:ListBucket 权限,并禁用桶的公开 ACL。避免在对象级 ACL 中授予 AllUsers 写权限,防止数据被意外覆盖或删除。
2.5 S3 协议核心交互流程
下图展示了 PostgreSQL 网关通过 S3 协议与对象存储交互的典型流程,重点体现查询优化中的关键步骤:
2.6 桶与对象的逻辑结构
下图展示了桶内对象的逻辑组织方式,以及 PostgreSQL 网关如何利用键前缀实现分区裁剪:
2.7 存储类选择策略
在 PostgreSQL 集成场景中,存储类的选择直接影响查询延迟与成本。建议遵循以下策略:
- 热数据(最近 30 天):使用 S3 Standard 或 Intelligent-Tiering,确保毫秒级首字节延迟,支持高频分析查询。
- 温数据(30-90 天):使用 S3 Standard-IA,降低存储成本,仍保持毫秒级访问。
- 冷数据(90 天以上):使用 S3 Glacier Instant Retrieval,存储成本大幅降低,但需注意最低 90 天存储时长。
- 归档数据(合规保留):使用 S3 Glacier Deep Archive,仅在审计或回溯查询时手动恢复。
transition: 30d -> Standard-IA; 90d -> Glacier Instant Retrieval; 365d -> Deep Archive。PostgreSQL 网关在查询时需感知存储类,避免直接扫描冻结对象。
2.8 ACL 配置示例
以下示例展示如何通过 AWS CLI 设置桶 ACL,允许特定账户读取对象:
# 授予账户 ID "123456789012" 对桶 "my-analytics-bucket" 的 READ 权限
aws s3api put-bucket-acl \
--bucket my-analytics-bucket \
--grant-read 'id=123456789012'
# 授予所有经过身份验证的用户对对象 "logs/2025/04/01/data.parquet" 的读取权限
aws s3api put-object-acl \
--bucket my-analytics-bucket \
--key logs/2025/04/01/data.parquet \
--grant-read 'uri=http://acs.amazonaws.com/groups/global/AuthenticatedUsers'
# 查看当前 ACL
aws s3api get-bucket-acl --bucket my-analytics-bucket
AllUsers 组授予公开读写权限。对于 PostgreSQL 网关访问,应使用 IAM 角色与桶策略组合,而非 ACL。桶策略支持条件键(如 aws:SourceIp、aws:Referer),提供更细粒度的控制。