Mysql/Apache seltsames CPU-Leistungsmuster

Mysql/Apache seltsames CPU-Leistungsmuster

Ich habe seit einigen Wochen mit einem Leistungsproblem auf einem meiner Server zu kämpfen.

Konfiguration: Dedizierter Server mit Ubuntu 16.04, Mysql 5.7.21 (alles MyISAM), Apache 2.4.18 (mpm prefork), Php 7.0.25. 128 GB RAM

Das CPU-Nutzungsmuster ist wirklich seltsam und ich habe keine Erklärung dafür gefunden. https://i.stack.imgur.com/88VMm.jpg

Wie Sie sehen, gibt es aufeinanderfolgende Stufen der CPU-Auslastung, die ziemlich konstant sind. Wenn die Apache-CPU-Auslastung zunimmt, nimmt auch die Mysql-CPU-Auslastung zu, und wenn eine abnimmt, nimmt auch die andere ab. Wie Sie sehen, liegt der ganze Unterschied in der CPU-Systemauslastung.

Ich habe mir die Anzahl der Abfragen/s von MySQL angesehen, die im Grunde konstant ist. Dasselbe gilt für die Anzahl der Anfragen/s bei Apache2. Ziemlich konstant. Übrigens benötigt der Apache-Server etwa 100 Anfragen/s und MySQL etwa 300 Anfragen/s bei MySQL (die CPU-Spitzen scheinen also nicht mit einer regelmäßig hohen Anzahl von Anfragen bei Apache oder MySQL zusammenzuhängen).

Ich habe mir langsame Abfragen angesehen, nichts Besonderes. Wenn ich SHOW PROCESSLIST ausführe, ist keine Abfrage mehr vorhanden. Dasselbe gilt für Apache. Die maximale Seitenladezeit beträgt <1 s.

Wenn ich den Apache2-Dienst neu starte, scheint das Muster für einige Stunden zu verschwinden. Wenn ich den MySQL-Dienst neu starte, scheint das Muster ebenfalls für einige Stunden zu verschwinden.

Außerdem habe ich ein paar andere Java-Dienste, die diese Datenbank ebenfalls verwenden (mit dem neuesten JDBC-Treiber, und ich sehe bei ihnen keine Änderung des CPU-Musters). Sie haben ihre Verbindung zu MySQL zunächst beim Start der Dienste hergestellt, aber ich habe dieses Verhalten geändert, um die Verbindung alle 5 Minuten zu schließen/eine neue zu starten ... Das hat nichts geändert

Meine my.cnf-Datei:

[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

Mein Apache hat so ziemlich die Standardkonfiguration, außer dass er (ich kann ungefähr 350 Worker verwenden, deshalb habe ich diesen Wert eingegeben)

MaxRequestWorkers 1024
ServerLimit 1024

Ich bin wirklich nicht sicher, was ich als nächstes tun soll, um dies zu untersuchen.

Irgendeine Idee, was schief laufen könnte?

Danke !

Bearbeiten: Ich habe in den Apache- oder MySQL-Protokollen nichts Verdächtiges gesehen

Bearbeiten: Einige Daten wurden in den Kommentaren abgefragt

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

GLOBALEN STATUS ANZEIGEN ->https://pastebin.com/AehMqQQq

GLOBALE VARIABLEN ANZEIGEN ->https://pastebin.com/JyGquqFx

Mysql-Tuner-Ausgabe:https://pastebin.com/F8wvbHec

Mir ist gerade aufgefallen, dass ich während dieser "hohen System-CPU"-Phase einen hohen CPU-Prozentsatz in isolate_freepages_block habe(Ich habe das mit perf top) erreicht. Trotzdem bin ich nicht sicher, wie ich das lösen soll

Antwort1

Dies sind alles dynamische Variablen, die mit SET GLOBAL xxx=xxx gesetzt werden können; bitte halten Sie sich an die gewünschte Reihenfolge. Wenn Sie nur EINE pro Tag machen, herunterfahren und neu starten, dauert es zwar viele Tage, aber dann läuft es sehr gut.
FORSCHEN Sie und verfolgen Sie es, wenn die Zeit es erlaubt; seltsame Nutzungsmuster werden während dieses Optimierungszyklus wahrscheinlich verschwinden.

Vorschläge für Ihren my.cnf/ini [mysqld]-Abschnitt

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

zu Beginn Ihrer SESSION, nur wenn Sie es brauchen, SET @max_allowed_packet=67108864 # um den RAM-Footprint zu reduzieren MySQLTuner berichtete

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

die nächsten 3 (alle 3 an einem Tag durchführen) verbessern die MyISAM key_buffer-Verwaltung

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

Wenn Sie eine SSD haben, gibt es weitere Möglichkeiten. Vor ungefähr einem Tag in einem Kommentar gefragt.

Antwort2

  • Wechseln Sie von MyISAM zu InnoDB. (Und ändern Sie key_buffer_sizeund innodb_buffer_pool_size.)
  • Senken Sie MaxRequestWorkers 1024und max_connections = 512– Es ist besser, neue Leute davon abzuhalten, den Lebensmittelladen zu betreten, als den Laden so überfüllt zu haben, dass sich niemand bewegen kann. 270 Max_used_connectionsKann sogar auf eine „donnernde Herde“ hinweisen.
  • Der Abfrage-Cache istwahrscheinlichmehr schaden als helfen. In ausgelasteten Produktionssystemen mit vielenschreibt, die QC muss oft geleert werden. Wechseln Sie daher unabhängig von anderen Tests zu query_cache_type=0und query_cache_size=0.
  • Überprüfen Sie die Garbage Collection von Java.

Ich werde sie gerne prüfen SHOW GLOBAL STATUS;und SHOW VARIABLESerneut veröffentlichen (sie sind abgelaufen).

verwandte Informationen