Kann die E/A-Latenz dazu führen, dass ein einfaches UPDATE in MySQL Sekunden dauert?

StackOverflow https://stackoverflow.com//questions/9655638

  •  11-12-2019
  •  | 
  •  

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 auf O_DSYNC oder O_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 in Innodb_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:

  1. 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.

  2. Wenn es sich nicht um Festplatten-E/A handeln kann, Kann ich außer der Anmietung eines dedizierten Servers noch etwas anderes ausprobieren?

War es hilfreich?

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:

  1. Eine schlechte I/O-Leistung kann MySQL tatsächlich zum Crawlen bringen.Es ist nicht klar Warumoder Wann genau, aber es passiert.

  2. Die Verlangsamung gilt für beide Auswahl und Updates, wobei Updates mehr leiden.

  3. 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.

  4. 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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top