我在 2 台主机上进行了 postgresql 流复制,并且面临两台服务器之间性能差异的问题。看起来一台主机上的所有 SQL 查询比另一台主机上慢 70-90%。
首先,我检查了两台服务器的查询报告,发现主服务器上的几乎所有查询都比备用服务器上的相应查询慢。我在两台主机上测试了几个示例查询,得到了相同的结果 - 主机上的查询执行速度比备用服务器上的查询慢。
我猜想,问题在于不同的电源管理。但两台主机上的电源管理均已禁用,未启用任何扩展调节器,并且“/sys/devices/system/cpu/cpuX/”中没有“cpufreq”目录
接下来我比较了硬件,只发现一个区别,较慢的主机有较新的 CPU,而较快的待机有较新的 CPU。
Master(速度较慢)
CPU1 Version: Intel(R) Xeon(R) CPU E5630 @ 2.53GHz --- Signature: Type 0, Family 6, Model 44, Stepping 2
CPU2 Version: Intel(R) Xeon(R) CPU E5630 @ 2.53GHz --- Signature: Type 0, Family 6, Model 44, Stepping 2
16x DDR3 DIMM 4096MB 1333MHz
待机(速度更快)
CPU1 Version: Intel(R) Xeon(R) CPU E5530 @ 2.40GHz --- Signature: Type 0, Family 6, Model 26, Stepping 5
CPU2 Version: Intel(R) Xeon(R) CPU E5530 @ 2.40GHz --- Signature: Type 0, Family 6, Model 26, Stepping 5
16x DDR3 DIMM 4096MB 1333MHz
如您所见,主机拥有较新的 E5630 CPU,但它们的运行速度比较旧的 E5530 慢。内存配置相同(使用 lshw -C 内存进行比较),只有供应商和序列号不同。
接下来,我使用 Intel Memory Latency Checker 检查了内存(两个主机都支持 NUMA),并得到了以下结果:主
$ sudo ./mlc-linux/mlc_avx512 --latency_matrix
Intel(R) Memory Latency Checker - v3.5
Command line parameters: --latency_matrix
Using buffer size of 200.000MB
Measuring idle latencies (in ns)...
Numa node
Numa node 0 1
0 366.1 228.9
1 386.9 218.0
$ sudo ./mlc-linux/mlc_avx512 --bandwidth_matrix
Intel(R) Memory Latency Checker - v3.5
Command line parameters: --bandwidth_matrix
Using buffer size of 100.000MB/thread for reads and an additional 100.000MB/thread for writes
Measuring Memory Bandwidths between nodes within system
Bandwidths are in MB/sec (1 MB/sec = 1,000,000 Bytes/sec)
Using all the threads from each core if Hyper-threading is enabled
Using Read-only traffic type
Numa node
Numa node 0 1
0 6021.5 5102.2
1 4799.6 6473.1
支持
$ sudo ./mlc-linux/mlc_avx512 --latency_matrix
Intel(R) Memory Latency Checker - v3.5
Command line parameters: --latency_matrix
Using buffer size of 200.000MB
Measuring idle latencies (in ns)...
Numa node
Numa node 0 1
0 82.3 130.1
1 129.4 80.1
$ sudo ./mlc-linux/mlc_avx512 --bandwidth_matrix
Intel(R) Memory Latency Checker - v3.5
Command line parameters: --bandwidth_matrix
Using buffer size of 100.000MB/thread for reads and an additional 100.000MB/thread for writes
Measuring Memory Bandwidths between nodes within system
Bandwidths are in MB/sec (1 MB/sec = 1,000,000 Bytes/sec)
Using all the threads from each core if Hyper-threading is enabled
Using Read-only traffic type
Numa node
Numa node 0 1
0 13439.5 7736.3
1 7749.9 13846.2
嗯,理想情况下,两台主机上的情况看起来应该相同 - 访问远程区域的速度必须比访问本地区域的速度慢。但事实并非如此,如果备用主机上一切正常,主主机上的一切都是错误的。1) 0->0 上的本地访问比远程 0->1 上的访问慢。为什么?2) 主主机上的访问时间明显大于备用主机上的访问时间,218ns vs 80ns(在最佳情况下),即使主主机有较新的 CPU。我尝试了几次测试,得到了类似的结果。
我还以为结果可能取决于主服务器处于生产负载下,而其备用服务器处于空闲状态。但这个负载不是很高,平均负载约为 3,87、3,85、3,70。
两台服务器上的 Sysctl 是相同的,只有一个 sysctl 键系列存在很大差异 -内核.sched_domain.cpu*.domain*.max_newidle_lb_cost。我没有找到有关此参数的任何信息,但我尝试更改它,并且它会在一段时间后动态地改变。
两个主机上的 PostgreSQL 配置(postgresql.conf)相同。
测试的查询不消耗磁盘 IO(通过提供查询详细信息的 pg_stat_statements contrib 模块检查),所有数据集完全在内存中(共享缓冲区)。测试的查询在两台服务器上具有相同的执行计划,但它们的执行时间不同。
我还考虑了最近的 meltdown/spectre 漏洞,检查了系统并发现了以下差异。具有较新 CPU 的主主机已完全缓解 spectre_v2 问题。
$ for i in $(sudo ls -1 /sys/devices/system/cpu/vulnerabilities/); do echo $i $(sudo cat /sys/devices/system/cpu/vulnerabilities/$i); done
meltdown Mitigation: PTI
spec_store_bypass Vulnerable
spectre_v1 Mitigation: Load fences
spectre_v2 Mitigation: Full retpoline
与备用主机
$ for i in $(sudo ls -1 /sys/devices/system/cpu/vulnerabilities/); do echo $i $(sudo cat /sys/devices/system/cpu/vulnerabilities/$i); done
meltdown Mitigation: PTI
spec_store_bypass Vulnerable
spectre_v1 Mitigation: Load fences
spectre_v2 Vulnerable: Retpoline without IBPB
好吧,我通过“/sys/kernel/debug/x86/*_enabled”禁用了所有保护,但这根本没有帮助(重新启用它们)
那么,有人能解释一下主服务器出了什么问题吗?为什么它的内存访问和现代 CPU 运行速度要慢得多?以及如何解决这个问题?