S3 的请求计费为何 GET 和 PUT 价格不同 - 存储 I/O 的经济学
从写入的内部成本、纠删码、一致性保证机制解析 S3 的 GET 请求费用仅为 PUT 十分之一的原因,并介绍优化请求费用的实用技巧。
GET 与 PUT 的价格差 - 10 倍的差距
S3 Standard 的定价体系中,PUT/COPY/POST/LIST 请求每 1,000 次 0.005 USD,GET/SELECT 请求每 1,000 次 0.0004 USD (us-east-1 的情况)。PUT 约为 GET 的 12.5 倍。这个价格差并非随意设定,而是反映了 AWS 的内部成本结构。写入 (PUT) 比读取 (GET) 对 S3 内部基础设施造成的负载要大得多。PUT 请求到达时,S3 需要将数据冗余写入多个物理设备、更新元数据索引、执行保证一致性的同步处理。GET 请求只需从元数据索引确定数据的物理位置,从一个副本中读取数据即可。由于写入的计算量、I/O 量、网络带宽消耗更大,因此定价更高。
写入的内部成本 - 纠删码与冗余化
S3 为实现 11 个 9 (99.999999999%) 的耐久性,使用纠删码对数据进行冗余化。纠删码是将数据分割为多个分片并添加奇偶校验分片的技术,即使部分分片丢失也能恢复数据。执行 PUT 请求时,S3 用纠删码对对象数据进行编码,将生成的分片写入跨多个 AZ 的多个物理设备。这个写入过程在确认所有分片正常保存之前不会完成。自 2020 年 12 月 S3 引入强一致性 (Strong Consistency) 以来,保证 PUT 之后立即执行 GET 能返回最新数据。为了这个一致性保证,PUT 需要同步更新元数据索引,产生额外的延迟和成本。GET 只需从元数据索引读取最新数据的位置,读取部分分片并解码即可。与写入相比处理更轻量。
不同存储类别的请求费用差异
S3 的存储类别不同,请求费用差异很大。S3 Standard 的 GET 每 1,000 次 0.0004 USD,而 S3 Glacier Flexible Retrieval 的 GET (恢复请求) 每 1,000 次 0.05 USD,是前者的 125 倍。Glacier 请求费用高的原因在于数据的物理存储方式。Glacier 将数据保存在离线或近线存储介质上,读取需要介质挂载和数据传输等物理操作。这些操作成本反映在请求费用中。S3 Intelligent-Tiering 根据访问模式自动将对象移动到最优存储类别。频繁访问的对象保留在 Standard 层,30 天未访问的移至 Infrequent Access 层,90 天未访问的移至 Archive Instant Access 层。虽然有监控费用 (每 1,000 个对象每月 0.0025 USD),但对于访问模式难以预测的工作负载,比手动管理存储类别更具成本效益。
优化请求费用的实用技巧
请求费用成为问题的场景是大量读写小对象的工作负载。PUT 100 万个 1KB 的对象,请求费用为 5 USD,而存储费用仅为 0.023 USD。请求费用是存储费用的 200 倍以上。第一种优化手法是将小对象合并为大对象。将 1,000 个 1KB 的对象合并为 1 个 1MB 的对象,PUT 请求数减少到千分之一。读取时使用 S3 Select 或 Range GET 仅获取所需部分。第二种手法是最小化 LIST 请求。LIST 与 PUT 收费相同 (每 1,000 次 0.005 USD)。对拥有大量对象的存储桶频繁执行 LIST 会导致费用膨胀。如果需要对象列表,使用 S3 Inventory 定期将存储桶内容导出为 CSV/ORC/Parquet 格式,再用 Athena 分析会更便宜。第三种手法是将 CloudFront 作为缓存层。如果对同一对象有大量 GET 请求,CloudFront 缓存可以大幅减少对 S3 的 GET 请求数。
DELETE 请求免费的原因
S3 的 DELETE 请求是免费的。这乍看之下令人费解。DELETE 也需要更新元数据索引,内部确实产生了成本。DELETE 免费的原因是促使客户释放资源的激励设计。如果删除不需要的对象需要收费,客户会犹豫是否删除,导致不需要的数据积累。不需要的数据积累会压缩 S3 的存储容量,增加 AWS 的基础设施成本。通过将 DELETE 设为免费,促使客户积极删除不需要的数据,实现存储的高效利用。同样的设计思想也体现在生命周期策略中。通过生命周期策略自动删除对象或自动迁移存储类别都不收取额外费用。AWS 有意设计了让客户容易采取成本优化行动的定价体系。要系统学习 S3 的成本优化,可参考相关专业书籍 (Amazon)。