我们刚刚开始研究使用 Postgres 作为我们系统的后端,该系统将用于 OLTP 类型的工作负载:> 95%(可能 >99%)的事务会将 1 行插入 4 个单独的表中,或更新1 行。我们的测试机器在具有 4 核 i7 处理器和传统 7200 RPM 磁盘的适度云托管 Windows VM 上运行 9.5.6(使用开箱即用的配置选项)。这比我们的目标生产硬件要慢得多,但现在对于发现我们基本设计中的瓶颈非常有用。
我们最初的测试非常令人沮丧。尽管插入语句本身运行得相当快(合并执行时间约为 2 毫秒),但总事务时间约为 40 毫秒,因为提交语句需要 38 毫秒。此外,在一个简单的 3 分钟负载测试(5000 个事务)中,我们每秒只看到大约 30 个事务,pgbadger 报告在“提交”中花费了 3 分钟(平均 38 毫秒),接下来最高的语句是分别在 10 (2ms) 和 3 (0.6 ms) 处插入。在此测试期间,postgres 实例上的 cpu 固定为 100%
提交所花费的时间等于测试经过的时间这一事实告诉我,不仅提交是序列化的(不足为奇,考虑到该系统上的磁盘相对较慢),而且在此期间它正在消耗 CPU,这让我感到惊讶。我之前会假设如果我们是 i/o 绑定的,我们会看到非常低的 cpu 使用率,而不是高使用率。
通过阅读,似乎使用异步提交可以解决很多这些问题,但需要注意崩溃/立即关闭时数据丢失。同样,将事务组合到一个开始/提交块中,或者使用多行插入语法也可以提高吞吐量。
我们可以使用所有这些选项,但在传统的 OLTP 应用程序中,它们都不会(您需要快速、原子、同步的事务)。20 年前,在比这台测试机器慢得多的硬件上运行的其他 RDBM 上,每秒 35 个事务在 4 核机器上是不可接受的,这让我认为我们做错了,因为我确信 Postgres 能够处理更高的工作量。
我环顾四周,但找不到一些可以作为调整 Postgres 实例的起点的常识配置选项。有什么建议么?