Tenho a replicação de streaming do postgresql em dois hosts e enfrentei o problema de desempenho diferente comparado entre dois servidores. Parece que todas as consultas sql em um host são mais lentas em 70-90% do que em outro.
Inicialmente, verifiquei os relatórios de consulta dos dois servidores e descobri que quase todas as consultas no relatório do mestre são mais lentas do que as consultas correspondentes do relatório de espera. Eu testei várias consultas de exemplo em ambos os hosts e obtive o mesmo resultado - as consultas no host mestre estão sendo executadas mais lentamente do que no modo de espera.
Eu supus, o problema é um gerenciamento de energia diferente. Mas o gerenciamento de energia está desabilitado em ambos os hosts, não há reguladores de escalonamento habilitados e nenhum diretório "cpufreq" em "/ sys / devices / system / cpu / cpuX /"
Em seguida, comparei o hardware e encontrei apenas uma diferença, o host mais lento tem CPUs mais recentes do que o de espera mais rápido.
Mestre (que é mais lento)
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
Modo de espera (mais rápido)
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
Como você pode ver, o host mestre possui CPUs E5630 mais recentes, mas elas funcionam mais lentamente com o E5530 mais antigo. A configuração da memória é a mesma (comparada usando a memória lshw -C), existem apenas números de série e de fornecedores diferentes.
Em seguida, peguei o Intel Memory Latency Checker, verifiquei a memória (ambos os hosts são NUMA aware) e obtive os seguintes resultados: mestre
$ 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
espera
$ 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
Bem, idealmente, a imagem em ambos os hosts deve ser a mesma - o acesso à zona remota tem que ser mais lento que o local. Mas não é, se tudo estiver ok no host de espera, em hosts mestre tudo está errado. 1) o acesso local em 0- > 0 é mais lento do que no remoto 0- > 1. Por quê? 2) os tempos de acesso no master são significativamente maiores do que em standby, 218ns vs 80ns (nos melhores casos), embora o master tenha CPUs mais recentes. Eu tentei testes várias vezes e obtive resultados semelhantes.
Além disso, achei que talvez os resultados dependam do fato de o servidor mestre estar sob carga de produção e sua espera estar inativa. Mas esta carga não é tão alta, a média de carga é de cerca de 3,87, 3,85, 3,70.
O sysctl em ambos os servidores é o mesmo, existe apenas uma família de chaves sysctl que difere significativamente - kernel.sched_domain.cpu * .domain * .max_newidle_lb_cost . Não encontrei nenhuma informação sobre esse parâmetro, mas tentei alterá-lo e ele muda dinamicamente depois de algum tempo.
A configuração do PostgreSQL (postgresql.conf) é a mesma nos dois hosts.
As consultas testadas não consomem e o disco IO (verificado através do módulo contrib pg_stat_statements que fornece detalhes da consulta), todo o conjunto de dados está completamente na memória (buffers compartilhados). As consultas testadas têm o mesmo plano de execução em ambos os servidores, mas seu tempo de execução é diferente.
Eu também pensei sobre as vuls recentes de fusão / espectro, verifiquei os sistemas e descobri a seguinte diferença. O host mestre com CPUs mais recentes tem mitigação completa de 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
vs. host de espera
$ 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
Bem. ok, eu desabilitei todas as proteções através de "/ sys / kernel / debug / x86 / * _ enabled", mas isso não ajudou em nada (as habilitou de volta)
Então, alguém pode explicar o que há de errado com o servidor master e por que seu acesso à memória e CPUs modernas funcionam muito mais devagar? E como corrigir esse problema?