
1、前言
最近经历了几次与IOPS相关的案例,感觉确实有必要对这块儿进行下阶段性的总结了。云上PostgreSQL的管理与维护,与本地部署对比起来,确实有一些不一样的地方。出了问题,甚至更棘手。因为你面对的是成千上万的客户,而不是面对一家客户。你对资源的掌控也不是100%完全拥有,因而对事件的响应速度也不一定能如你所愿。
SAP BTP的云中采用的PostgreSQL底层仍然来源于AWS、Azure、GCP、AliCloud几家。因而最底层的服务质量,是IaaS以及SAP提供的服务质量的叠加,有一种木桶理论的味道,只要有一边响应不及时,整个的服务对于故障时处理的响应就受影响了。
本文,就对AWS中用于PostgreSQL RDS的相关IOPS指标的规定以及使用进行一次总结。SAP BTP云将所有AWS相关区域,在全球范围内,全部定义编号为1-区,以1打头。
2、分析
Amazon RDS 提供三种存储类型:预调配 IOPS SSD(也称为 io1 和 io2 Block Express)、通用型 SSD(也称为 gp2 和 gp3)和磁性存储(也称为标准存储)。它们的性能特性和价格不同,这意味着您可以根据数据库工作负载需求定制存储性能和成本。您可以创建具有多达 64 TiB 存储的 Db2、MySQL、MariaDB、Oracle、SQL Server 和 PostgreSQL RDS 数据库实例。RDS for Db2 不支持 gp3 和磁性存储类型。(原文参考: https://docs.aws.amazon.com/zh_cn/AmazonRDS/latest/UserGuide/CHAP_Storage.html#USER_PIOPS)
这三种存储类型分别是:
1. 预调配 IOPS SSD – 预调配 IOPS 存储符合输入/输出密集型工作负载(尤其是数据库工作负载)的需求,此类工作负载需要低输入/输出延迟和一致的输入/输出吞吐量。预调配 IOPS 存储最适合生产环境。(io1和io2 Block Express)
2. 通用型 SSD – 通用型 SSD 卷提供了经济高效的存储,适用于在中等规模的数据库实例上运行的各种工作负载。通用型存储最适合开发和测试环境。(gp2和gp3), 注意这里提到了中等规模的数据库实例。
3. 磁性 – Amazon RDS 还支持磁性存储以实现向后兼容。建议您采用通用型 SSD 或预调配 IOPS SSD 来满足所有新存储需求。磁性存储上的数据库实例允许的最大存储量为 3 TiB。这个基本上是用于旧版,不被推荐。
使用能用型或预调配SSD时,有下边的对应关系:
| 数据库引擎 | Amazon RDS 存储大小 | 预调配的卷数 |
|---|---|---|
| MariaDB、MySQL 和 PostgreSQL | 小于 400GiB | 1 |
| MariaDB、MySQL 和 PostgreSQL | 400–65536GiB | 4 |
注意一个让人吃惊的变态的提示:
当您修改实例的存储以使其从一个卷变为四个卷时,或者当您使用磁性存储修改实例时,Amazon RDS 不使用“弹性卷”功能。相反,Amazon RDS 会预调配新卷,并将数据从旧卷透明地移到新卷。此操作会同时消耗新旧卷的大量 IOPS 和吞吐量。根据卷的大小和修改期间存在的数据库工作负载量,此操作可能会消耗大量 IOPS,显著增加 I/O 延迟,需要几个小时才能完成,而 RDS 实例保持为 Modifying 状态。
这就意味着,如果你将存储容量大小,从小于400G调到400或以上时,就会产生上述移到新卷的操作。如果工作负载重,可能要几个小时才能完成。AWS的云平台上的一些所谓的神话,在这里一点都不好看。
2.1、预置IOPS SSD存储
预调配 IOPS 存储是一种存储类型,它提供了可预测的性能以及一致的低延迟。
预调配 IOPS 存储针对要求性能一致的联机事务处理(OLTP)工作负载进行了优化。
预调配 IOPS 可帮助这些工作负载的性能优化。
在创建数据库实例时,可以指定 IOPS 速率和卷的大小。
它提供两种类型:io2 Block Express 存储(推荐) 和 io1 存储(上一代)。
2.1.1、io2 Block Express 存储
可以使用预调配 IOPS SSD io2 Block Express 存储,以实现高达每秒 256,000 次 I/O 操作(IOPS)。io2 Block Express 卷的吞吐量因每个卷的预调配 IOPS 量和正在运行的 I/O 操作的规模而异。
我们看下PostgreSQL相关的对应的指标:
| 数据库引擎 | 存储大小的范围 | 预调配 IOPS 的范围 | 最大吞吐量 |
|---|---|---|---|
| Db2、MariaDB、MySQL 和 PostgreSQL | 100–65536GiB | 1000–256000 IOPS | 4,000 MiB/s |
100G到65TB的存储量范围。IOPS与存储范围的结束关系如下:
1. IOPS 与已分配存储(以 GiB 为单位)的比率必须不超过 1000:1。对于不基于 AWS Nitro 系统的数据库实例,该比率为 500:1。
说法是说,如果是100GB的存储容量,你的IOPS最多可以设置为100000 IOPS,如果不基于Nitro系统, 最多只能为50000 IOPS
2. 示例:可以为 256GiB 和更大的卷预置最多 IOPS(1000IOPS x 256GiB = 256000IOPS)。对于不基于 AWS Nitro 系统的数据库实例,最大 IOPS 可达到 512GiB(500IOPS x 512GiB = 256000 IOPS)。
3. 吞吐量按比例扩展至每个预置 IOPS 0.256 Mib/s。在 256000 IOPS 下,当 I/O 大小为 16KiB 时,最大吞吐量可以达到 4000MiB/s;在 I/O 大小为 256KiB 时,可以实现 16000 IOPS 或更高的吞吐量。对于不基于 AWS Nitro 系统的数据库实例,在 128000 IOPS 下,当 I/O 大小为 16KiB 时,最大吞吐量可达到 2000MiB/s。
这个是根据I/O大小来进行计算实际的吞吐量的。看到没,有一次16K的,也有一次256K的。得到的结果也是不同的。
4. 如果您使用存储自动扩展,IOPS 和最大存储阈值(以 GiB 为单位)之间的比率也同样适用。
2.1.2、io1存储(上一代)
对于 I/O 密集型工作负载,您可以使用预调配 IOPS SSD io1 存储,并实现每秒高达 256,000 次的 I/O 操作(IOPS)。现在已经不推荐使用io1了,毕竟是上一代的方案了。具体的预置方案如下:
| 数据库引擎 | 存储大小的范围 | 预调配 IOPS 的范围 | 最大吞吐量 |
|---|---|---|---|
| Db2、MariaDB、MySQL 和 PostgreSQL | 100–399GiB | 1000 – 19950 IOPS | 500 MiB/s |
| Db2、MariaDB、MySQL 和 PostgreSQL | 400–65536GiB | 1000–256000 IOPS | 4,000 MiB/s |
400GB是一个重要的分水岭。
1. 在 RDS for SQL Server 上,IOPS 与已分配存储(以 GiB 为单位)的比率必须为 1–50,而在其他 RDS 数据库引擎上必须为 0.5–50。对于PostgreSQL而言,最小0.5, 最大50的倍量关系可以设置IOPS。
2. 如果您使用存储自动扩展,IOPS 和最大存储阈值(以 GiB 为单位)之间的比率也同样适用。
对于预置IOPS存储而言,您需要为预配置的资源付费,因此在规定月份中无论是否使用这些资源,您都需为此支付费用。这是AWS比较狠的地方,等于躺赚。
2.2、通用型SSD存储
通用存储提供了经济高效的存储性能,可用于大多数对延迟或性能不敏感的数据库工作负载。与使用预调配 IOPS 存储的实例相比,使用通用型存储的数据库实例会经历更久的延迟(相对而言)。
2.2.1、gp3存储(推荐)
通过使用通用型 gp3 存储卷,您可以独立于存储容量自定义存储性能。存储性能是每秒输入/输出操作数(IOPS)与存储卷可执行读取和写入的速度(存储吞吐量)的组合。在 gp3 存储卷上,Amazon RDS 提供的基准存储性能为 3000 IOPS 和 125MiB/s。
对于除 RDS For SQL Server 之外的每个 RDS 数据库引擎,当 gp3 卷的存储大小达到某个阈值时,基准存储性能将得到提高。这是因为卷条带化,其中存储使用四个卷而不是一个卷。RDS for SQL Server 不支持卷条带化,因此没有阈值。对于带区卷,Amazon RDS 提供的基准存储性能为 12,000 IOPS 和 500 MiB/s。
看看与PostgreSQL相关的指标限制:
| 数据库引擎 | 存储大小 | 基准存储性能 | 预调配 IOPS 的范围 | 预调配存储吞吐量的范围 |
|---|---|---|---|---|
| Db2、MariaDB、MySQL 和 PostgreSQL | 20–399 GiB | 3000 IOPS/125MiB/s | 不适用 | 不适用 |
| Db2、MariaDB、MySQL 和 PostgreSQL | 400–65536GiB | 12000 IOPS/500MiB/s | 12,000–64,000IOPS | 500 – 4000MiB/s |
400GiB也是一个分水岭。怎么讲,20~399GB,IOPS是稳定在3000的。同时吞吐量最多也不会超过125M/s。不会提供任何弹性的。只有过了400以后,支持4个条带,一下子变成了原来的4倍了。同时,也只有在400GB以后,才可以进行IOPS的预调配。
gp3卷存储的相关约束如下:
1. 对于所有支持的数据库引擎,存储吞吐量与 IOPS 的最大比率为 0.25。
2. 在 RDS for SQL Server 上,IOPS 与已分配存储(以 GiB 为单位)的最小比率为 0.5。其他支持的数据库引擎没有最低比率。
3. 对于所有支持的数据库引擎,IOPS 与已分配存储的最大比率为 500。
4. 如果您使用存储自动扩展,IOPS 和最大存储阈值(以 GiB 为单位)之间的比率也同样适用。
2.2.2、gp2存储(上一代)
当您的应用程序不需要高存储性能时,您可以使用通用型 SSD gp2 存储。gp2 存储的基准输入/输出性能为 3IOPS/GiB,最少具有 100IOPS。这种关系意味着较大的卷具有更好的性能。例如,一个 100GiB 卷的基准性能为 300 IOPS。一个 1000GiB 卷的基准性能为 3000 IOPS。
大小低于 1000GiB 的单独 gp2 卷也有能力在延长的时间内突增至 3000 IOPS。卷 I/O 积分余额决定突增性能。许多工作负载从不会耗尽突增余额。不过,某些工作负载可能会用完 3000 IOPS 突增存储积分余额,因此,应计划存储容量以满足您的工作负载需求。
对于大于 4,000 GiB 的 gp2 卷,基准性能大于突增性能。对于这些卷,因为基准性能优于 3000 IOPS 突发性能,所以突发性能并不重要。但是,对于某些引擎和大小的数据库实例,存储跨四个卷进行条带化,可提供单个卷的四倍基准吞吐量和四倍突增 IOPS。
与PostgreSQL相关的存储大小、IOPS以及吞吐量的对应关系如下:
| 数据库引擎 | RDS 存储大小 | 基准 IOPS 的范围 | 基准吞吐量的范围 | 突增 IOPS |
|---|---|---|---|---|
| MariaDB、MySQL 和 PostgreSQL | 5–399GiB¹ | 100 - 1197 IOPS | 128 - 250MiB/s | 3000 |
| MariaDB、MySQL 和 PostgreSQL | 400–1335GiB | 1200 - 4005 IOPS | 500 - 1000MiB/s | 12000 |
| MariaDB、MySQL 和 PostgreSQL | 1336–3999GiB | 4008 - 11997 IOPS | 1,000 MiB/s | 12000 |
| MariaDB、MySQL 和 PostgreSQL | 4000–65536GiB | 12000 - 64000 IOPS | 1,000 MiB/s | 不适用² |
2.3、AWS RDS SSD存储类型总结汇总
下边的内容直接摘自原文,还是蛮有用的。
| 特征 | 预调配 IOPS(io2 Block Express) | 预调配 IOPS(io1) | 通用型(gp3) | 通用型(gp2) |
|---|---|---|---|---|
| 描述 | RDS 存储组合中性能最高(IOPS、吞吐量、延迟)专为延迟敏感型、事务工作负载而设计 | 一致的存储性能(IOPS、吞吐量、延迟)专为延迟敏感型、事务工作负载而设计 | 可灵活地独立预调配存储、IOPS 和吞吐量平衡各种事务性工作负载的性价比 | 提供可突增的 IOPS平衡各种事务性工作负载的性价比 |
| 使用案例 | 需要亚毫秒延迟和高达 256000 IOPS 的持续 IOPS 性能的业务关键型事务性工作负载 | 需要最多 256000IOPS 的持续 IOPS 性能的事务性工作负载 | 在开发/测试环境中,在中型关系数据库上运行的广泛工作负载 | 在开发/测试环境中,在中型关系数据库上运行的广泛工作负载 |
| 延迟 | 亚毫秒,在 99.9% 的时间内始终提供 | 一位数毫秒,在 99.9% 的时间内始终提供 | 一位数毫秒,在 99% 的时间内始终提供 | 一位数毫秒,在 99% 的时间内始终提供 |
| 卷大小 | 100–65536GiB | 100–65536GiB(在 RDS for SQL Server 上为 20–16384GiB) | 20–65536GiB(在 RDS for SQL Server 上为 16384GiB) | 20–65536GiB(在 RDS for SQL Server 上为 16384GiB) |
| 最大 IOPS | 256,000 | 256,000(在 RDS for SQL Server 上为 64,000) | 64,000(在 RDS for SQL Server 上为 16,000) | 64,000(在 RDS for SQL Server 上为 16,000)注意您无法直接在 gp2 存储上预调配 IOPS。IOPS 因分配的存储大小而异。 |
| 最大吞吐量 | 根据预调配 IOPS 卷扩展至最多 4,000MB/s吞吐量按比例扩展至每个预置 IOPS 0.256 Mib/s。在 256000 IOPS 下,当 I/O 大小为 16KiB 时,最大吞吐量可以达到 4000MiB/s;在 I/O 大小为 256KiB 时,可以实现 16000 IOPS 或更高的吞吐量。对于不基于 AWS Nitro 系统的实例,在 128000 IOPS 下,当 I/O 大小为 16KiB 时,最大吞吐量可达到 2000MiB/s。 | 根据预调配 IOPS 卷扩展至最多 4,000MB/s | 预调配多达 4000MB/s 的额外吞吐量(对于 RDS for SQL Server,为 1000MB/s) | 1000MB/s(RDS for SQL Server 上为 250MB/s) |
| AWS CLI 及 RDS API 名称 | io2 | io1 | gp3 | gp2 |
2.4、旧版磁性存储(非SSD存储)
这个已经很少有人用了。它有如下的这些限制:
1. 不允许您在使用 SQL Server 数据库引擎时扩展存储。
2. 使用 SQL Server 数据库引擎时,不允许转换为其它存储类型。
3. 不支持存储自动伸缩。
4. 不支持弹性卷。
5. 限制为 3 TiB 的最大大小。
6. 限制为最大 1,000 IOPS。
2.5、监控存储性能
1. IOPS – 每秒完成的 I/O 操作数。该指标作为给定时间间隔内 IOPS 平均值进行报告。Amazon RDS 每隔 1 分钟分别报告读取和写入 IOPS。总 IOPS 是读取和写入 IOPS 的总和。IOPS 的典型值在零到每秒数万次之间。
2. 延迟 – 从提交 I/O 请求到完成请求之间的已用时间。该指标作为给定时间间隔内延迟平均值进行报告。Amazon RDS 每分钟分别报告一次读取和写入延迟。典型的延迟值以毫秒 (ms) 为单位。
3. 吞吐量 – 每秒传输到磁盘或从磁盘中传输的字节数。该指标作为给定时间间隔内吞吐量平均值进行报告。Amazon RDS 每隔 1 分钟分别报告读取和写入吞吐量,所用单位为每秒字节数(B/s)。吞吐量的典型值在零到 I/O 通道的最大带宽之间。
4. 队列深度 – 队列中等待处理的 I/O 请求数。这些是由应用程序提交但由于设备忙于处理其他 I/O 请求而尚未发送到设备的 I/O 请求。在队列中等待所花的时间是延迟和处理时间的一部分(不以指标形式提供)。该指标作为给定时间间隔内队列深度平均值进行报告。Amazon RDS 每隔 1 分钟报告队列深度。队列深度典型值在零至数百之间。
测量的 IOPS 值与单个 I/O 操作的大小无关。这意味着,在您度量输入/输出性能时,确保查看实例的吞吐量,而不是输入/输出操作数量。
3、总结
回到SAP BTP中使用AWS的PostgreSQL RDS,它默认采用的是gp3存储。并且存储容量起步都小于400GB。这意味着刚开始的时候,IOPS的上限也就定格在3000,如果遇到高并发的业务运行的时候,就需要对IOPS值进行预配。
这些都可以通过日常监控得到平均峰值。根据实际情况进行调整。
有时候也会出现极端的情况,就是IOPS并没有达到峰值,但是因为应用代码的问题,导致存储容量耗尽,最后IOPS瞬间也会持续为3000IOPS直至用光全部存储。这种情况多见于大量的临时文件生成(AWS把数据文件以及SQL查询执行时需要用的临时文件都记入到存储容量当中,临时文件最后释放时,可用存储容量又会得到部分恢复)。这一点,监控的时候要非常小心。
我们就曾经遇到过几次这样的坑。明明数据库的整体大小,很小。可实际报上来的storage usage就是远超。结果发现是它生成了大量的临时文件,当然,可能还有相应的WAL log文件(待考)。这种大小上的不匹配往往会给监控维护人员很大的启示,并去尽力寻找生成大量临时文件原因。
-- temp space consuming most
SELECT
userid::regrole, temp_blks_written as stat,
(select datname from pg_database where oid = dbid) as dbid,
query
FROM
pg_stat_statements
WHERE userid::regrole::varchar = 'dbo'
ORDER BY
temp_blks_written DESC
LIMIT 100;
举例说明,我们通过上边的SQL就可以得到写入临时快最多的是哪些SQL语句。当然,这个SQL语句能使用的前提是:系统安装好了pg_stat_statement扩展。这是SAP BTP中HyperScaler PG的标配。
本文试图将IOPS以及AWS的RDS存储方式从前到后,完整的理一遍。只有了解了它的存储方式,IOPS的计算规则,你才能充分利用规则,做好监控,最后采取一个相对合理的节省成本的方式提供满意的PostgreSQL服务。
我是【Sean】, 欢迎大家长按关注并加星公众号:数据库杂记。有好资源相送,同时为你提供及时更新。已关注的朋友,发送0、1到7,都有好资源相送。

往期导读:
1. 小福利: ULID---另一种半有序高效全局ID出现了
2. 小心使用UUID, PostgreSQL中的UUID的弊端及解决方案
3. 一个有关UUID字段相关类型的有趣案例
4. PostgreSQL SQL的基础使用及技巧
5. PostgreSQL开发技术基础:过程与函数
6. PostgreSQL从一个搭建环境比较常见的小问题说起
7. PostgreSQL中使用pgcompacttable 和 pg_repack回收表膨胀的空间的对比
8. 熊大 - 原来HANA DB抓连接数也很容易
9. SAP BTP中的PostgreSQL数据库膨胀应对方法




