Xeon E5 上的服务器应用程序性能比 Xeon E3 差 2 倍

Server app on Xeon E5 has 2x worse performance than on Xeon E3

服务器应用程序在本地主机上使用 postgres。它在 Xeon E3-1270 V2 @ 3.50Ghz 和 16 GB RAM 上运行良好,处理超过 1k db requests/second。该应用程序创建了约 100 个 ThreadPool 线程。

同一应用在 E5 上启动时(相同配置)使用 500 或更多线程,直到达到 max_connections。有时事务执行非常慢(开始平均需要 0.18 秒,最大需要 15.94 秒;提交平均需要 0.47 秒,最大需要 15.93 秒)。慢速查询可以非常简单,比如更新一行中的两个整数列。 pg_stat_statements 中没有有问题的查询。我不得不将 ThreadPool min/max 个线程限制为 100 个,否则 postgres 会在 600+ 个连接时耗尽内存。

在某些情况下执行 ~12 秒的典型代码:

        using (var s = HibernateSessionFactory.OpenSession())
        using (var tr = s.BeginTransaction())
        {
            try
            {
                try
                {
                    s.Lock(User, LockMode.None);
                }
                catch
                {
                    s.Lock(User, LockMode.None);
                }

                User.Guild = null;
                tr.Commit();
            }
            catch
            {
                tr.Rollback();
                throw;
            }
        }

当应用程序停止响应客户端请求时,pgAdmin "Server Status" 显示这些查询:

 set extra_float_digits=3; set ssl_recognitation_limit=0; select 'npgsql12345';
 DISCARD ALL
 COMMIT
 BEGIN; SET TRANSACTION ISOLATION LEVEL READ COMMITED;

和 ~2000 个授予的锁 是什么原因导致的?

根据您提供的数据,问题的关键似乎是线程数增加了 5 倍——E3 为 100,而 E5 为 500。你说过它们在硬件方面是相同的配置,我假设这意味着每个都有 4 个超线程内核,因为根据 Intel 规范 sheet.

这意味着在 CPU 可用线程数相同的情况下,您要尝试处理 5 倍多的线程。这也会极大地增加内存需求,并且还会增加 CPU 开销,因为它可能会在尝试在所有线程之间进行上下文切换时摇摆不定。鉴于 E5 也有 16 GB 的 RAM(基于您的相同配置评论),它可能无法应对增加的开销。

我会看看您是否正在将大量数据交换到磁盘,这会导致可怕的 I/O 性能,以及事情是否受到 CPU 或 I/O 的限制。我猜你 运行ning Windows 基于 C# 的使用,所以我建议使用 Resource Monitor 之类的东西来深入研究。也就是说,用它来监视 Postgres 进程并查看它们的磁盘使用情况、CPU 使用情况等。该工具提供了多种监视选项。

然而,除此之外,为什么不只是 运行 在 E5 上使用相同的工作负载(100 个线程)来与 E3 一起工作?如果其他配置相同,主要区别(取决于确切的 E5 模型)将是 CPU 频率,同时在每个 CPU 线程的基础上提供一些边际边缘,而不是较慢的时钟速度E3,不太可能比 E3 有更大的性能优势(相对于,比如说,如果您的 E5 有 24 个内核或 48 个线程)。显然,需要进行一些性能测试和调整才能确定真正的红线,但我怀疑它更接近 100 个线程而不是 500 个线程。

如果您 运行 在 E5 上使用最多 100 个线程,就像在 E3 上一样,性能是否良好(基本相同)?你说了 "helped",但不清楚是否还更糟。

当你需要很多连接或高性能时,使用像 pgBouncer 或 pgPool 这样的连接池。您的应用程序应该连接到连接池中的可用连接。使用这样的硬件,您应该在池和数据库之间使用大约 20 到 50 个连接,仅此而已。额外的连接会减慢数据库的速度。确切的连接数取决于使用模式,但数百个连接绝不是一个好主意,它表现不佳。

我有一台 2 处理器 12 核机器(E5,总共 24 个超线程),仅需 20 个连接即可提供最高性能:2500 tps。而且它使用的是 FusionIO 卡,IO 不是真正的问题。该应用程序是用 pl/pgsql 编写的,正在使用 200GB 的数据进行相当复杂的计算。

我使用 pgbench 检查服务器性能。这要么是 postgresql 服务器问题,要么是机器问题(硬盘驱动器之类的)。在这两种情况下,这都与编程无关。