Padrão estranho de desempenho da CPU do Mysql/Apache

Padrão estranho de desempenho da CPU do Mysql/Apache

Estou enfrentando um problema de desempenho em um dos meus servidores há algumas semanas.

Configuração: Servidor dedicado com Ubuntu 16.04, Mysql 5.7.21 (todos MyISAM), Apache 2.4.18 (mpm prefork), Php 7.0.25. 128 GB de RAM

O padrão de uso da CPU é muito estranho e não encontrei nada que explicasse isso. https://i.stack.imgur.com/88VMm.jpg

Como você pode ver, existem níveis sucessivos de uso da CPU, que são bastante constantes. Além disso, quando o uso da CPU do Apache aumenta, o uso da CPU do MySQL aumenta e quando um diminui, o outro diminui. Além disso, como você pode ver, toda a diferença acontece no uso da CPU do sistema.

Eu dei uma olhada no número de consultas do mysql, que é basicamente constante. A mesma coisa para o número de solicitações/s no Apache2. Bastante constante. A propósito, o servidor apache leva cerca de 100req/s e o mysql tem aproximadamente 300 consultas/s no mysql (portanto, os picos na CPU não parecem estar vinculados a uma grande quantidade regular de solicitações no apache ou mysql)

Dei uma olhada em consultas lentas, nada em particular. Quando faço um SHOW PROCESSLIST, nenhuma consulta ainda existe. A mesma coisa para o Apache. O tempo máximo de carregamento da página é <1s.

Quando reinicio o serviço Apache2, o padrão parece desaparecer por algumas horas. Quando reinicio o serviço mysql, o padrão também parece desaparecer por algumas horas.

Além disso, tenho alguns outros serviços Java que também usam esse banco de dados (usando o driver jdbc mais recente e não vejo nenhuma alteração no padrão de CPU com eles). Inicialmente estavam criando a conexão deles com o mysql no início dos serviços, mas mudei esse comportamento para fechar a conexão/iniciar uma nova a cada 5min... Isso não mudou nada

Meu arquivo meu.cnf:

[mysqld_safe]
socket      = /var/run/mysqld/mysqld.sock
nice        = 0
[mysqld]
user        = mysql
pid-file    = /var/run/mysqld/mysqld.pid
socket      = /var/run/mysqld/mysqld.sock
port        = 3306
basedir     = /usr
datadir     = /var/lib/mysql
tmpdir      = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
bind-address        = 0.0.0.0
key_buffer_size = 36G
max_allowed_packet = 64M
tmp_table_size = 256M
max_heap_table_size = 256M
max_connections = 512
table_open_cache = 8192
bulk_insert_buffer_size = 512M
thread_stack        = 192K
thread_cache_size       = 8
sort_buffer_size = 64M
myisam_sort_buffer_size = 64M
myisam-recover-options  = BACKUP
query_cache_limit   = 1M
query_cache_size        = 16M
log_error = /var/log/mysql/error.log
expire_logs_days    = 10
max_binlog_size   = 100M
[isamchk]
key_buffer_size = 36G
sort_buffer_size = 8M
read_buffer = 4M
write_buffer = 4M

Meu apache tem praticamente a configuração padrão, exceto que tem (posso ter cerca de 350 trabalhadores usados, é por isso que coloquei esse valor)

MaxRequestWorkers 1024
ServerLimit 1024

Eu realmente não tenho certeza do que fazer a seguir para investigar.

Alguma idéia do que poderia estar errado?

Obrigado !

Editar: não vi nada suspeito nos logs do Apache ou MySQL

Edit: Alguns dados solicitados nos comentários

ulimit -a:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 514833
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 50000
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 514833
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

iostat -x

Linux 4.4.0-112-generic (ns340707.ip-37-187-250.eu)     02/21/2018      _x86_64_        (12 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          14.89    0.29   10.42    1.41    0.00   72.98

Device:         rrqm/s   wrqm/s     r/s     w/s    rkB/s    wkB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
sdb               0.70    51.90   18.37   11.86  1179.98  1894.25   203.33     1.40   46.40   10.29  102.33   2.35   7.11
sda               0.73    51.89   25.27   11.87  1847.55  1894.25   201.50     1.22   32.72    4.37   93.05   2.14   7.93
md0               0.00     0.00    9.63   62.19   758.90  1889.96    73.77     0.00    0.00    0.00    0.00   0.00   0.00
nvme1n1           0.00     0.00  429.64 1214.09  4755.77  6215.04    13.35     0.36    0.19    0.18    0.19   0.03   5.00
md2               0.00     0.00 1567.33 1204.69 14913.87  6204.69    15.24     0.00    0.00    0.00    0.00   0.00   0.00
nvme0n1           0.00     0.00 1204.85 1215.25 10676.20  6219.68    13.96     1.57    0.62    0.14    1.10   0.05  11.93

MOSTRAR STATUS GLOBAL ->https://pastebin.com/AehMqQQq

MOSTRAR VARIÁVEIS GLOBAIS ->https://pastebin.com/JyGquqFx

Saída do sintonizador MySQL:https://pastebin.com/F8wvbHec

Acabei de notar que, durante a fase de "alta CPU do sistema", tenho uma alta% de CPU em isolado_freepages_block(Eu consegui isso usando perf top). No entanto, não tenho certeza de como resolver isso

Responder1

Estas são todas variáveis ​​dinâmicas que podem ser definidas com SET GLOBAL xxx=xxx; por favor siga a ordem solicitada. Se você fizer apenas UM por dia, desligue e reinicie, faltam muitos dias, mas você está funcionando muito bem.
PESQUISE e prossiga conforme o tempo permitir, o padrão de uso estranho provavelmente desaparecerá durante este ciclo de ajuste.

Sugestões para sua seção my.cnf/ini [mysqld]

max_connections=325  #from 512 to support 270 max_used_connections
#max_allowed_packet=64M  # lead for 1M default  WHEN YOU NEED more

no início de sua SESSÃO, somente quando você precisar, SET @max_allowed_packet=67108864 # para reduzir o consumo de RAM relatado pelo MySQLTuner

query_cache_size=0  # from 16M, not being used, conserve RAM
query_cache_limit=1K  # from 1M, conserve RAM
query_cache_min_res_unit=512  #from 4096, for > results stored, if ever used
thread_cache_size=100  # from 8 to reduce ~ 240,000 threads_created a day

os próximos 3 (fazer todos os 3 em um dia) irão aprimorar o gerenciamento de key_buffer do MyISAM

key_cache_division_limit=50  # from 100 default  for Hot/Warm separation
key_cache_block_size=64K  # from 1K let's clear more RAM when full
key_cache_age_threshold=64800  # from 300 KEEP 18 HRS vs 5M to reduce RD RPS

innodb_lru_scan_depth=128  # from 1024 to conserve CPU cycles
innodb_stats_sample_pages=32  # from 8 to improve statistics cardinality
max_seeks_for_key=32  # from a huge # to limit OPTIMIZER depth
max_write_lock_count=16  # from a huge # to allow RD after NN write locks
table_open_cache=16000  # from 8192 to support ~ 350,000 opened_tables daily

Se você tiver algum SSD, há mais oportunidades. Perguntado em um comentário há cerca de um dia.

Responder2

  • Mude de MyISAM para InnoDB. (E mudar key_buffer_sizee innodb_buffer_pool_size.)
  • Abaixe MaxRequestWorkers 1024e max_connections = 512- É melhor impedir que novas pessoas entrem no supermercado do que deixar a loja tão lotada que ninguém possa se mover. Even 270 Max_used_connectionspode indicar 'rebanho trovejante'.
  • O cache de consulta éprovavelmentemachucar mais do que ajudar. Em sistemas de produção movimentados, com muitosescreve, o QC precisa ser muito liberado. Portanto, independente de outros testes, mude para query_cache_type=0e query_cache_size=0.
  • Verifique a coleta de lixo do Java.

Ficarei feliz em analisá-los SHOW GLOBAL STATUS;e SHOW VARIABLESse você os repassar (eles expiraram).

informação relacionada