一文读懂 AWS S3

一文读懂 AWS S3

AWS S3 全名是 Simple Storage Service,简便的存储服务。为什么这么起名啊?它:

  1. 提供了统一的接口 REST/SOAP 来统一访问任何数据
  2. 对 S3 来说,存在里面的数据就是对象名(键),和数据(值)
  3. 不限量,单个文件最高可达 5TB
  4. 高速。每个 bucket 下每秒可达 3500 PUT/COPY/POST/DELETE 或 5500 GET/HEAD 请求
  5. 具备版本,权限控制能力
  6. 具备数据生命周期管理能力

作为一个对象存储服务,S3 功能真的很完备。如果不用搭梯子,访问快,我还真想过拿它来做自己的网盘。

基本概念

Bucket

要存储数据在 S3 里,首先我们要建立一个 Bucket。Bucket 默认是不公开的。

Bucket 有几个特点:

  • 命名需全球唯一。每个帐号默认可建 100 个,可申请至最多 1000 个
  • 创建者的拥有权不可转让,也不可以从一个 Region 转去别的 Region
  • 没有对象存储数量限制

Bucket 就像是电脑里面的某一个顶层分区。所有的对象都必须保存在某一个 bucket 下面。

Object

Bucket 里面每一个存储的数据就是对象,由对象名(键),和数据(值)组成。

对象的键(Key)可以很长,甚至按照一定前缀格式来指定,从而模拟文件夹的层级结构,比如 Photo/Family/2020-01-25-new-year/altogether.jpg

每一个对象其实还包含一些元信息(Meta-data),包括系统指定的文件类型,创建时间,加密算法等,和用户上传时指定的元信息。元信息在对象创建后都无法更改。

我们也可以为对象指定最多 10个标签(Tag),标签的键和值的最大长度是 128 和 256 个字符。这个标签和元信息有什么不同呢?标签是可以修改和新增的。它最大的好处,是可以结合权限控制,生命周期管理,和数据分析等使用。

单个文件上传最大是 5GB。超过的话,需要使用 multipart upload API。最大支持 5TB。

一致性特性

对程序员来说,这么一个类似数据库的东西,肯定需要关心它的读写特性和一致性模型。

  • 没有锁的功能。如果同时(几乎)发起两个更新对象的 PUT 请求,键相同,那么,以到达 S3 时间先后处理更新。
  • 不同对象的更新,没法做到原子操作。
  • 对全新的对象来说,它是 Read-after-Write Consistency 的。也就是写了之后马上读,肯定就是你刚才上传的数据。
  • 如果你要更新数据,那就变成 Eventual Consistency 了。也就是说,更新后马上读,可能是旧的数据,也可能是新的。

这里有一个比较坑的地方是,如果你先调用 GET 请求访问一个不存在的资源,S3 告诉你它不存在。然后你马上上传数据,再调用一个 GET,这时候是有可能拿不回来的。

存储级别

作为一个“云盘”,S3 的好处是可以把你存储的数据,按不同的存储级别来计费。这个存储级别是每个对象不同,上传时指定的。

我们看看不同的场景,应该选择哪种级别的存储:

  • 经常访问的数据对象
  1. STANDARD - 这是最普通,最常用的类型
  2. REDUCED_REDUNDANCY (RRS) - 不建议使用。仅为不重要,可再建数据设计,还有每年平均 0.01% 数据丢失的可能性。
  • 按访问频率自动优化的数据
  1. INTELLIGENT_TIERING - 可以智能地把不热门的数据自动转级别。但是,每个文件最低收费标准是 128KB,存 30天。
  • 不经常访问的数据
  1. STANDARD_IA
  2. ONEZONE_IA

AWS 一个 Region,有两到三个 Zone。这两种级别的区别就是,One Zone 的数据就单点保存,丢了就丢了。

  • 归档的数据
  1. S3 Glacier - 最低保存 90天。取出时间 1分钟至 12小时。
  2. S3 Glacier Deep Archive - 最低保存 180天。默认 12小时内取出。

S3 计费的大头主要是存储容量。但是,S3 还会按照数据获取的次数,和传输容量来计费。越不常访问的级别,虽然存储便宜,但是访问贵。INTELLIGENT_TIERING 还会收监测和管理费用。

生命周期的管理

除了手动指定,或者使用 INTELLIGENT_TIERING 外,S3 其实还可以让我们在 bucket 上定义生命周期管理的策略(Policy),来自动转换对象的存储级别。

生命周期的管理可以做到: 1. 转换存储级别 2. 过期删除

数据安全

数据安全,是数据存储服务非常重要的一部分。S3 提供了很多方面的功能来保障这一点。

多版本

不小心把数据删除了的痛,程序员应该都懂。但是,后悔药是没有的。所以,我们很多时候并不会做永久删除,而是实现软删除的功能。S3 就提供了多版本的功能。只要 bucket 打开了多版本的选项,每次对象的更新都会新加一个版本,而不是覆盖。删除对象,也只是新增一个删除标识。

当然,你要强行删除特定版本的数据也是可以的,它只是让这件事变得难一些而已。它甚至可以把 bucket 设置成只有通过 MFA 认证的请求才能实现永久删除。

要注意的是: 1. 打开版本控制的 bucket,是没法关闭的,顶多可以暂停。也就是说,暂停后的 bucket,新加对象的时候,版本 id 会设为 null。 2. 无论打开,或者暂停版本控制,对 bucket 内已经存在的对象是没有影响的。

锁定

除了使用多版本控制让覆盖或者删除变得更难,S3 还可以锁定特定版本的对象。这种模型被称为 write-once-read-many (WORM)。

有两种锁定的方式: 设定保留期限 - 在某固定期限内,对象 WORM。 法定留存 - 仅当这个留存标识被删除后,对象才能被覆盖或删除。

一个特定版本的对象,可以同时设置这两种保护,或任意一种。

因为锁定是针对特定版本的对象,如果你的更改或删除操作请求只根据对象的键,那它还是允许你新增一个版本,或加上删除标识。只是这个锁定,还能防止对象因为生命周期的设置而被删除掉。

服务端加密

数据传输过程(in-transit)中的保护,现在基本都由 SSL/TLS 来实现的。AWS 也提供 VPN 或者网络直连服务。

S3 提供了服务端数据加密的功能,可实现数据的存储(at rest)方面的安全。不过它只支持对称加密,不支持非对称加密。虽然你可以本地把数据加密了再上传到 S3,但是,这需要自己保护好密钥,其实更不容易。

服务端加密开启后,bucket 内已经存在的对象不会被自动加密。而且,只有数据被加密,元信息(meta data),标签(Tag)不会被加密。

S3 的服务端加密有三种方式:

  1. SSE-S3 - S3 自管理的密钥,使用 AES-256 加密算法。每个对象的密钥不同,并且它还被定期更换的主密钥同时加密。
  2. SSE-KMS - 密钥存放在 KMS(软硬件结合的密钥管理系统)。
  3. SSE-C - 在请求时自己提供密钥,S3 只管加解密逻辑和存储。S3 不保存密钥,只保存随机加盐的 HMAC 值来验证今后请求的合法性。

这里主要说一下 S3 使用 SSE-KMS 特点:

  • 启用前,如果没有指定客户管理的 CMK(customer master key),S3 会自动创建一个由 AWS 管理的 CMK
  • 加密数据的密钥,同时也被加密,并和数据保存在一起
  • 有请求频率限制
  • 只支持对称密钥
  • CMK 必须和 bucket 在同一个区(Region)

IAM 集成


陈鹄:一文读懂 AWS IAMzhuanlan.zhihu.com图标

前一篇文章详细介绍了 AWS IAM 的功能,S3 当然能根据 IAM 的设置来控制权限。S3 的资源,除了 bucket 和 object 外,还包含了一些子资源。

Bucket 子资源: lifecycle website versioning policy cors logging

Object 子资源: acl restore

在了解 S3 如何控制权限以前,我们要理解资源的拥有者这个概念。在 S3 里面,资源是谁创建的,它所属的 AWS 帐号,就是这个资源的拥有者。有一种情况是,Bucket 是帐号 A 创建的。但是 A 允许 B 在里面创建对象 X。这个 X 的拥有者是 B 而不是 A。如果资源拥有者授权 A,A 可以把自己的权限委托给自己帐号内的其它人,但不可以再一次跨帐号授权。

S3 如何验证请求

当 S3 收到请求时,会经过下面几个步骤验证请求:

  1. 把所有相关的策略(user policy, bucket policy, ACL)集合起来。
  2. 根据下面 3 小步,拿出全集中的合适子集来分别验证:
  3. 用户范畴 如果请求发起者是 IAM User 或 Role,它所属的 aws 帐号就会先检查它是否有权限做这种类型的操作(user policy)。假如刚好要操作的资源(bucket 或 object)属于当前帐号,那么就同时检查相应的 bucket policy, bucket ACL 和 object ACL。
    如果请求发起者不属于 IAM,则跳至下一步。
  4. Bucket 范畴 S3 会检查拥有 bucket 的 aws 帐号的策略。
    如果操作的是 bucket,那请求的用户需要有 bucket owner 赋予的权限。 如果操作的是对象,需要检查 bucket owner 是否有显式 deny 对象的设置。
  5. Object 范畴 当请求是关于对象的时,最后检查对象 owner 的策略子集。

天啊,这看上去好复杂。其实,和一个小孩想玩玩具一样

首先,小孩必须获得父母的请求,可以玩玩具。然后,看这个玩具拥有者是谁,如果是自己父母,就看这个玩具是否能给孩子玩(比如可能年龄还不合适,超时等)。如果这个玩具是其它人的,那就要还获得其它人的允许。

不同策略的场景

对于 S3 验证请求的时候,需要验证的那几种不同的策略,究竟各自的使用场景是什么呢?

  • Object ACL
  1. 唯一一种管理保存在他人 bucket 里的对象权限的方式
  2. 定义在单个对象级别
  3. 最多包含 100 个授权信息
  • Bucket ACL
  1. 唯一推荐使用的场景是为 S3 Log Delivery 赋予写访问日志的权限
  2. 虽然可以配置跨帐号权限,但仅仅支持有限的设置
  • Bucket Policy
  1. 能给自己帐号内的用户赋权
  2. 支持所有 S3 操作的跨帐号权限设置
  3. Policy 自身大小不超过 20KB
  • User Policy
  1. 能给自己帐号内的用户赋权

副本备份

S3 不仅通过多点存储提高健壮性,还提供了自动的异步数据备份的功能。不仅支持同 Region,不同 bucket 的备份,还支持跨 Region,不同帐号的备份。要开启副本备份,首先必须在源和目标 bucket 同时打开多版本的设置。

为什么要使用?

  • 备份同时保留元数据
  • 备份至不同存储级别
  • 更改备份数据的拥有权
  • 15 分钟内自动备份

什么时候跨区备份(CRR)

  • 满足监管需求
  • 减少数据传输延时(地域原因)
  • 提高数据操作的效率

什么时候同区备份(SRR)

  • 合并日志
  • 生产和测试用户间数据同步
  • 满足数据主权法规

什么会同步?

  • 备份配置生效后新建的对象
  • 没加密的对象
  • 通过 SSE-S3 或者 SSE-KMS CMK(必须显式启用)加密的对象
  • 对象元数据
  • bucket 拥有者有权读取的对象
  • 对象 ACL 除非备份同属一个 aws 帐号
  • 对象标签
  • 对象的锁信息

什么不同步?

  • 备份配置生效前新建的对象
  • 使用 SSE-C 加密的对象
  • 保存在 Glacier 或 Glacier Deep Archive 的对象
  • bucket 级别子资源的更新
  • 由于生命周期配置导致的操作
  • 源 bucket 中本来就是副本的对象
  • 删除标识
  • 源 bucket 中被删除的特定版本的对象

知识小点与周边

路由请求

  • S3 使用的是 DNS 来接收转发请求。如果请求对象的 S3 地址不对,会返回一个临时的重定向。但是对那些 2019 年 3 月 20 日后启用的 Region,地址错误返回的则是 HTTP 400 状态。
  • S3 DNS 会按需更新 IP 地址。所以,对那些长期运行的客户端,可能需要采取特殊手段来更新 IP 信息。

静态资源网站

S3 的 bucket 可以直接配置为静态资源网站。但是需要结合 CloudFront 才能支持 HTTPS 访问。 请求者付费的 bucket,不允许设置为静态网站。

CloudFront 数据的分发支持两种类型:

  • Web Distribution
  • RTMP

Storage Gateway

当你本地服务器想要访问 AWS S3 的时候,除了 API,AWS 还提供了几种网关可供使用:

  • File Gateway - 像访问文件或者共享文件那样访问 S3 资源
  • Volume Gateway - 通过 iSCSI 设备的方式连接。细分为两种:
  • Stored Volumes - 所有数据都保存在本地,但是能异步备份到 S3
  • Cached Volumes - 所有的数据都保存到 S3,本地只存放经常访问的数据
  • Tape Gateway - 模拟磁带访问的网关,数据异步备份到 S3 Glacier 或 Glacier Deep Archive

Athena 和 Macie

Athena 是交互式的查询服务,无须部署。可使用 SQL 来查询 S3 数据。支持的数据格式包括:CSV,JSON,Apache Parquet。

Macie 是一种可通过 NLP 和 ML 来协助你发现,分类和保护敏感数据的服务。它可以扫描 S3 中的数据,看是否包含 PII(Personally Identifiable Information)或者涉及版权的数据。

原链

编辑于 03-10

文章被以下专栏收录