Postgres 的合理基本 OLTP 配置是什么?
What's a sensible basic OLTP configuration for Postgres?
我们刚刚开始研究使用 Postgres 作为我们系统的后端,该系统将用于 OLTP 类型的工作负载:> 95%(可能 >99%)的事务会将 1 行插入 4单独的表,或更新 1 行。我们的测试机器是 运行ning 9.5.6(使用开箱即用的配置选项)在一个适度的云托管 Windows VM 上,具有 4 核 i7 处理器,传统的 7200 RPM磁盘。这比我们的目标生产硬件慢得多,但现在对于找到我们基本设计中的瓶颈很有用。
我们的初始测试非常令人沮丧。尽管插入语句本身 运行 相当快(合并执行时间约为 2 毫秒),但由于提交语句耗时 38 毫秒,所以整个事务时间约为 40 毫秒。此外,在一个简单的 3 分钟负载测试(5000 个事务)中,我们每秒只看到大约 30 个事务,pgbadger 报告在 "commit"(平均 38 毫秒)中花费了 3 分钟,以及下一个最高的语句分别是 10(2 毫秒)和 3(0.6 毫秒)的插入。在此测试期间,postgres 实例上的 cpu 固定在 100%
提交所花费的时间等于测试所用时间的事实告诉我,提交不仅是序列化的(不足为奇,因为该系统上的磁盘相对较慢),而且它正在消耗cpu 在那段时间里,这让我感到惊讶。如果我们受到 i/o 约束,我会假设之前的事实是,我们会看到非常低的 cpu 使用率,而不是高使用率。
通过阅读,似乎使用异步提交可以解决很多此类问题,但需要注意 crashes/immediate 关机时数据丢失。同样,将事务组合到一个 begin/commit 块中,或使用多行插入语法也可以提高吞吐量。
我们可以使用所有这些选项,但在传统的 OLTP 应用程序中,none 是(您需要具有快速、原子、同步的事务)。在 4 核机器上每秒 35 个事务在 20 年前在其他 RDBM 上是不可接受的 运行ning 在比这台测试机器慢得多的硬件上,这让我认为我们做错了,因为我确保 Postgres 能够处理更高的工作负载。
我环顾四周,但找不到一些常识性的配置选项,可以作为调整 Postgres 实例的起点。有什么建议吗?
如果 COMMIT
是你的时间浪费,那可能意味着:
您的系统支持 FlushFileBuffers
系统调用,这是应该的。
你的 I/O 慢得可怜。
您可以通过在 postgresql.conf
中设置 <a href="https://www.postgresql.org/docs/current/static/runtime-config-wal.html#GUC-FSYNC" rel="nofollow noreferrer">fsync</a> = off
来测试它 – 但永远不要 在生产系统上执行此操作。如果这大大提高了性能,您就会知道 I/O 系统在实际必须将数据写入磁盘时非常慢。
在不牺牲数据持久性的情况下,PostgreSQL(或任何其他可靠的数据库)无法在这方面进行改进。
虽然看到一些良好的 OLTP 工作负载启动配置会很有趣,但我们已经解开了提交期间不合理的高 CPU 的谜团。事实证明它根本不是 Postgres,而是 Windows Defender 不断扫描 Postgres 数据文件。设置托管测试服务器的 VM 的团队不了解我们需要后端配置而不是用户配置。
我们刚刚开始研究使用 Postgres 作为我们系统的后端,该系统将用于 OLTP 类型的工作负载:> 95%(可能 >99%)的事务会将 1 行插入 4单独的表,或更新 1 行。我们的测试机器是 运行ning 9.5.6(使用开箱即用的配置选项)在一个适度的云托管 Windows VM 上,具有 4 核 i7 处理器,传统的 7200 RPM磁盘。这比我们的目标生产硬件慢得多,但现在对于找到我们基本设计中的瓶颈很有用。
我们的初始测试非常令人沮丧。尽管插入语句本身 运行 相当快(合并执行时间约为 2 毫秒),但由于提交语句耗时 38 毫秒,所以整个事务时间约为 40 毫秒。此外,在一个简单的 3 分钟负载测试(5000 个事务)中,我们每秒只看到大约 30 个事务,pgbadger 报告在 "commit"(平均 38 毫秒)中花费了 3 分钟,以及下一个最高的语句分别是 10(2 毫秒)和 3(0.6 毫秒)的插入。在此测试期间,postgres 实例上的 cpu 固定在 100%
提交所花费的时间等于测试所用时间的事实告诉我,提交不仅是序列化的(不足为奇,因为该系统上的磁盘相对较慢),而且它正在消耗cpu 在那段时间里,这让我感到惊讶。如果我们受到 i/o 约束,我会假设之前的事实是,我们会看到非常低的 cpu 使用率,而不是高使用率。
通过阅读,似乎使用异步提交可以解决很多此类问题,但需要注意 crashes/immediate 关机时数据丢失。同样,将事务组合到一个 begin/commit 块中,或使用多行插入语法也可以提高吞吐量。
我们可以使用所有这些选项,但在传统的 OLTP 应用程序中,none 是(您需要具有快速、原子、同步的事务)。在 4 核机器上每秒 35 个事务在 20 年前在其他 RDBM 上是不可接受的 运行ning 在比这台测试机器慢得多的硬件上,这让我认为我们做错了,因为我确保 Postgres 能够处理更高的工作负载。
我环顾四周,但找不到一些常识性的配置选项,可以作为调整 Postgres 实例的起点。有什么建议吗?
如果 COMMIT
是你的时间浪费,那可能意味着:
您的系统支持
FlushFileBuffers
系统调用,这是应该的。你的 I/O 慢得可怜。
您可以通过在 postgresql.conf
中设置 <a href="https://www.postgresql.org/docs/current/static/runtime-config-wal.html#GUC-FSYNC" rel="nofollow noreferrer">fsync</a> = off
来测试它 – 但永远不要 在生产系统上执行此操作。如果这大大提高了性能,您就会知道 I/O 系统在实际必须将数据写入磁盘时非常慢。
在不牺牲数据持久性的情况下,PostgreSQL(或任何其他可靠的数据库)无法在这方面进行改进。
虽然看到一些良好的 OLTP 工作负载启动配置会很有趣,但我们已经解开了提交期间不合理的高 CPU 的谜团。事实证明它根本不是 Postgres,而是 Windows Defender 不断扫描 Postgres 数据文件。设置托管测试服务器的 VM 的团队不了解我们需要后端配置而不是用户配置。