Kann die E/A-Latenz dazu führen, dass ein einfaches UPDATE in MySQL Sekunden dauert?
Frage
Bei meiner MySQL-Anwendung tritt ein Problem auf langsame Leistung beim Laufen einige UPDATE
, INSERT
Und DELETE
Abfragen.In dieser Frage werde ich nur auf eine einzelne Sache eingehen UPDATE
, weil es ausreicht, das Problem zu demonstrieren:
UPDATE projects SET ring = 5 WHERE id = 1
Das UPDATE
ist normalerweise schnell genug, etwa 0,2 ms, aber hin und wieder (genug, um ein Problem darzustellen) es dauert mehrere Sekunden.Hier ist ein Auszug aus dem Protokoll (siehe 4. Zeile):
~ (0.000282) UPDATE `projects` SET `ring` = 5 WHERE `id` = 1
~ (0.000214) UPDATE `projects` SET `ring` = 6 WHERE `id` = 1
~ (0.000238) UPDATE `projects` SET `ring` = 7 WHERE `id` = 1
~ (3.986502) UPDATE `projects` SET `ring` = 8 WHERE `id` = 1
~ (0.000186) UPDATE `projects` SET `ring` = 9 WHERE `id` = 1
~ (0.000217) UPDATE `projects` SET `ring` = 0 WHERE `id` = 1
~ (0.000162) UPDATE `projects` SET `ring` = 1 WHERE `id` = 1
projects
ist eine InnoDB-Tabelle mit 6 Spaltentypen INT
Und VARCHAR
, 17 Zeilen und ein Index auf id
.Das passiert auch bei anderen Tabellen, aber hier konzentriere ich mich auf diese.Bei dem Versuch, das Problem zu lösen, habe ich darauf geachtet, dass die Abfragen alle sequentiell waren, also ist dies der Fall kein Sperrproblem.Der UPDATE
oben wird im Kontext einer Transaktion ausgeführt.Andere Informationen auf dem Server:
- VPS mit 4 GB RAM (vorher 1 GB), 12 GB freier Festplattenspeicher
- CentoOS 5.8 (vorher 5.7)
- MySQL 5.5.10 (vorher 5.0.x)
Das „war“-Bit oben bedeutet, dass es vor oder nach dem Upgrade nicht funktioniert hat.
Was ich bisher versucht habe, ohne Erfolg:
- Einstellung
innodb_flush_log_at_trx_commit
auf 0, 1 oder 2 - Einstellung
innodb_locks_unsafe_for_binlog
an oder aus - Einstellung
timed_mutexes
an oder aus - Ändern
innodb_flush_method
von der Standardeinstellung aufO_DSYNC
oderO_DIRECT
- Zunehmend
innodb_buffer_pool_size
vom Standardwert auf 600 MB und dann auf 3000 MB - Zunehmend
innodb_log_file_size
vom Standardwert auf 128 MB - Kompilieren von MySQL aus dem Quellcode
- Läuft
SHOW PROCESSLIST
, was mich darüber informiert, dass der Status „aktualisiert“ wird - Läuft
SHOW PROFILE ALL
, was besagt, dass fast die gesamte Zeit für das „Aktualisieren“ aufgewendet wurde und dass innerhalb dieses Schritts nicht so viel Zeit für CPU-Zyklen aufgewendet wurde und es viele freiwillige Kontextwechsel gab (wie 30). - Überwachung
SHOW STATUS
für Änderungen inInnodb_buffer_pool_pages_dirty
.Möglicherweise besteht ein Zusammenhang zwischen dem Löschen schmutziger Seiten und den langsamen Abfragen, der Zusammenhang ist jedoch nicht klar.
Dann habe ich beschlossen, die I/O-Latenz des Systems mit zu überprüfen ioping
.Das ist also mein erster VPS Ich war überrascht, dieses Ergebnis zu sehen:
4096 bytes from . (vzfs /dev/vzfs): request=1 time=249.2 ms
4096 bytes from . (vzfs /dev/vzfs): request=2 time=12.3 ms
4096 bytes from . (vzfs /dev/vzfs): request=3 time=110.5 ms
4096 bytes from . (vzfs /dev/vzfs): request=4 time=232.8 ms
4096 bytes from . (vzfs /dev/vzfs): request=5 time=294.4 ms
4096 bytes from . (vzfs /dev/vzfs): request=6 time=704.7 ms
4096 bytes from . (vzfs /dev/vzfs): request=7 time=1115.0 ms
4096 bytes from . (vzfs /dev/vzfs): request=8 time=209.7 ms
4096 bytes from . (vzfs /dev/vzfs): request=9 time=64.2 ms
4096 bytes from . (vzfs /dev/vzfs): request=10 time=396.2 ms
Ziemlich unberechenbar, würde ich sagen.
Nachdem ich das alles gesagt habe, frage ich:
Kann die E/A-Latenz gelegentlich die Leistung von MySQL beeinträchtigen? Das habe ich immer gedacht, wenn du eine liefst
UPDATE
, würde der Thread, der sich um diese Verbindung kümmert, keine Daten auf die Festplatte schreiben oder auf eine solche Löschung warten;es würde sofort zurückkehren und das Spülen würde zu einem anderen Zeitpunkt von einem anderen Thread durchgeführt werden.Wenn es sich nicht um Festplatten-E/A handeln kann, Kann ich außer der Anmietung eines dedizierten Servers noch etwas anderes ausprobieren?
Lösung
Ich antworte auf meine eigene Frage mit zusätzlichen Daten, die ich basierend auf Ihren Antworten gesammelt habe.
Ich habe zwei Notebooks verwendet, die über ein drahtloses Netzwerk verbunden waren.Auf Notebook A habe ich ein Verzeichnis von Notebook B verwendet sshfs
.Dann startete AI auf Notebook MySQL, in dem dieses montierte Verzeichnis als Datenverzeichnis angegeben wurde.Dies sollte MySQL ein sehr langsames E/A -Gerät bieten.MySQL wurde mit gestartetinnodb_flush_log_at_trx_commit = 0
.
Ich habe 3 Sätze von Abfragen definiert, wobei jeder aus einer Aktualisierung bestand und eine ausgewählte Abfrage 10.000 Mal ohne explizite Transaktionen wiederholt wurde.Die Experimente waren:
- US1SID:Aktualisieren und wählen Sie eine bestimmte Zeile derselben Tabelle aus.Die gleiche Zeile wurde in allen Iterationen verwendet.
- US1MID:Aktualisieren und wählen Sie eine bestimmte Zeile derselben Tabelle aus.Die Reihe war in jeder Iteration anders.
- US2MID:Aktualisieren und Auswählen in Zeilen verschiedener Tabellen.In diesem Fall hat sich die Tabelle, die von der Auswahl gelesen wurde, während des Experiments überhaupt nicht geändert.
Jeder Satz wurde zweimal mit einem Shell-Skript ausgeführt (daher sind die Zeiten langsamer als in meiner ursprünglichen Frage), einmal unter normalen Bedingungen und das andere nach der Ausführung des folgenden Befehls:
tc qdisc replace dev wlan0 root handle 1:0 netem delay 200ms
Der obige Befehl fügt eine mittlere Verzögerung von 200 ms hinzu, wenn Pakete über wlan0 übertragen werden.
Erstens ist hier die mittlere Zeit der Top 99% schnellsten Updates und Auswahl sowie der unteren 1% -Updates und Auswahl.
| Delay: 0ms | Delay: 200ms |
| US1SID | US1MID | US2MID | US1SID | US1MID | US2MID |
| top99%u | 0.0064 | 0.0064 | 0.0064 | 0.0063 | 0.0063 | 0.0063 |
| top99%s | 0.0062 | 0.0063 | 0.0063 | 0.0062 | 0.0062 | 0.0062 |
| bot01%u | 1.1834 | 1.2239 | 0.9561 | 1.9461 | 1.7492 | 1.9731 |
| bot01%s | 0.4600 | 0.5391 | 0.3417 | 1.4424 | 1.1557 | 1.6426 |
Wie klar ist, dass MySQL auch mit wirklich, sehr schlechten E/A -Leistung sehr schnell die meisten Abfragen ausführen kann.Aber was mich am meisten betrifft, sind die schlimmsten Fälle. Hier ist also ein weiterer Tisch, der die 10 langsamsten Abfragen zeigt.Ein "u" bedeutet, dass es sich um ein Update handelte, ein "s" ein Auswahl.
| Delay: 0ms | Delay: 200ms |
| US1SID | US1MID | US2MID | US1SID | US1MID | US2MID |
| 5.443 u | 5.946 u | 5.315 u | 11.500 u | 10.860 u | 11.424 s |
| 5.581 u | 5.954 s | 5.466 u | 11.649 s | 10.995 u | 11.496 s |
| 5.863 s | 6.291 u | 5.658 u | 12.551 s | 11.020 u | 12.221 s |
| 6.192 u | 6.513 u | 5.685 u | 12.893 s | 11.370 s | 12.599 u |
| 6.560 u | 6.521 u | 5.736 u | 13.526 u | 11.387 u | 12.803 u |
| 6.562 u | 6.555 u | 5.743 u | 13.997 s | 11.497 u | 12.920 u |
| 6.872 u | 6.575 u | 5.869 u | 14.662 u | 12.825 u | 13.625 u |
| 6.887 u | 7.908 u | 5.996 u | 19.953 u | 12.860 u | 13.828 s |
| 6.937 u | 8.100 u | 6.330 u | 20.623 u | 14.015 u | 16.292 u |
| 8.665 u | 8.298 u | 6.893 u | 27.102 u | 22.042 s | 17.131 u |
Schlussfolgerungen:
Eine schlechte I/O-Leistung kann MySQL tatsächlich zum Crawlen bringen.Es ist nicht klar Warumoder Wann genau, aber es passiert.
Die Verlangsamung gilt für beide Auswahl und Updates, wobei Updates mehr leiden.
Aus irgendeinem Grund wurden sogar ausgewählte ausgewählte Tabellen, die nicht an Änderungen beteiligt waren und die kürzlich besiedelt worden waren, verlangsamt, wie aus den oben genannten US2MID hervorgeht.
In Bezug auf die von mentatkgs vorgeschlagenen Testfälle scheinen die Aktualisierung verschiedener Zeilen anstelle derselben ein wenig zu helfen, das Problem jedoch nicht zu lösen.
Ich denke, ich werde meine Software entweder anpassen, um solche Verzögerungen zu tolerieren oder zu einem anderen Anbieter zu wechseln.Das Mieten eines dedizierten Servers ist für dieses Projekt zu teuer.
Vielen Dank an alle für die Kommentare.
Andere Tipps
Wenn Sie Ihren VPS in der Cloud hosten, kann es sein, dass Sie auf Probleme stoßen, die völlig außerhalb Ihrer Kontrolle liegen.
VPS unterliegen den Launen der Hostserver, auf denen sie ausgeführt werden.Beispielsweise wird die CPU-Zykluspriorität in der Rackspace Cloud basierend auf der Größe des VPS gewichtet.Je größer Ihr VPS ist, desto größer ist die Wahrscheinlichkeit, dass Ihre App reibungslos funktioniert.Wenn auf dem von Ihnen verwendeten Host ein größerer VPS vorhanden ist, ist dies der Fall möglich dass gewichtetes Platzen daran schuld ist.Das ist ziemlich schwer zu sagen.
Haben Sie versucht, dies lokal auf Ihrem eigenen Computer auszuführen?Wenn es auf Ihrem eigenen System perfekt läuft und Sie eine garantierte Leistung benötigen, ist es am besten, auf einen dedizierten Server umzusteigen.
Sie haben ein VPS-bezogenes E/A-Problem.Es ist nicht die Schuld von MySQL.
Nutzen Sie zufällig den Elastic Block Store mit Amazon oder möglicherweise RDS?Beide verwenden Remote-Speicher und eine IP-Protokollschicht, um mit dem Speicher zu kommunizieren.Manchmal kann es zu unangenehmen Verzögerungen kommen.
Frage 1) Ja.
Um es zu überprüfen, schreiben Sie 2 Apps:
Testfall 1:Ich werde dies einige Stunden lang jede Minute tun
UPDATE `projects` SET `ring` = 5 WHERE `id` = 1
UPDATE `projects` SET `ring` = 6 WHERE `id` = 1
Testfall 2:Ich werde dies einige Stunden lang jede Minute tun
UPDATE `projects` SET `ring` = 7 WHERE `id` = 1
UPDATE `projects` SET `ring` = 8 WHERE `id` = 2
Testfall 1 sollte eine Verzögerung haben, Testfall 2 jedoch nicht.
Frage 2) Verwenden Sie eine NoSQL-Datenbank.