7

一部のクエリを実行すると、 MySQLアプリケーションのパフォーマンスが低下します。この質問では、問題を実証するのに十分であるため、特定の1つについてのみ説明します。UPDATEINSERTDELETEUPDATE

UPDATE projects SET ring = 5 WHERE id = 1

これUPDATEは通常、約0.2msと十分に高速ですが、ときどき(問題になるほど)数秒かかります。これがログからの抜粋です(4行目を見てください):

 ~ (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

projectsINTは、6列の型とVARCHAR、17行、および上のインデックスを持つInnoDBテーブルidです。他のテーブルでも起こりますが、ここではこれに焦点を当てています。問題を解決しようとしたとき、クエリがすべてシーケンシャルであることを確認したので、これはロックの問題ではありません。上記UPDATEは、トランザクションのコンテキストで実行されます。サーバーに関するその他の情報

  • 4GBのRAM(以前は1GB)、12GBの空きディスク容量を備えたVPS
  • CentoOS 5.8(以前は5.7)
  • MySQL 5.5.10(以前は5.0.x)

上記の「だった」ビットは、アップグレードの前後に機能しなかったことを意味します。

私がこれまでに試したことは無駄です:

  • innodb_flush_log_at_trx_commit0、1、または2に設定
  • innodb_locks_unsafe_for_binlogオンまたはオフの設定
  • timed_mutexesオンまたはオフの設定
  • innodb_flush_methodデフォルトからO_DSYNCまたはに変更O_DIRECT
  • innodb_buffer_pool_sizeデフォルトから600M、次に3000Mに増加
  • innodb_log_file_sizeデフォルトから128Mに増加
  • ソースからのMySQLのコンパイル
  • 実行中SHOW PROCESSLIST、状態が「更新中」であることを通知します
  • 実行中SHOW PROFILE ALL。これは、ほとんどすべての時間が「更新」に費やされ、そのステップ内では、CPUサイクルにそれほど多くの時間が費やされず、多くの自発的なコンテキストスイッチ(30など)があったことを示しています。
  • の変更を監視SHOW STATUSしますInnodb_buffer_pool_pages_dirty。フラッシュされるダーティページと遅いクエリの間には何らかの関係があるかもしれませんが、相関関係は明確ではありません。

次に、でシステムのI/O遅延を確認することにしましたioping。これは私の最初のVPSなので、この結果を見て驚いた

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

かなり不安定だと思います。

そのすべてを言ったので、私は尋ねます:

  1. I / OレイテンシーがMySQLのパフォーマンスを低下させることがありますか?UPDATEを実行すると、その接続を処理するスレッドがデータをディスクにフラッシュしたり、そのようなフラッシュを待機したりすることはないといつも思っていました。それはすぐに戻り、フラッシュは別の時間に別のスレッドによって実行されます。

  2. ディスクI/Oにできない場合、専用サーバーを借りる以外に、他に試すことができることはありますか?

4

4 に答える 4

2

私はあなたの回答に基づいて収集した追加のデータを使用して、私自身の質問に回答しています。

ワイヤレスネットワークで接続された2つのノートブックを使用しました。ノートブックAで、を使用してノートブックBのディレクトリをマウントしましたsshfs。次に、ノートブックでAIがMySQLを起動し、マウントされたディレクトリをデータディレクトリとして指定しました。これにより、MySQLに非常に遅いI/Oデバイスが提供されます。MySQLはで始まりました innodb_flush_log_at_trx_commit = 0

3セットのクエリを定義しました。各セットは、明示的なトランザクションなしで、更新と選択クエリを10,000回繰り返したもので構成されています。実験は次のとおりです。

  • US1SID:同じテーブルの特定の行を更新して選択します。すべての反復で同じ行が使用されました。
  • US1MID:同じテーブルの特定の行を更新して選択します。行は各反復で異なるものでした。
  • US2MID:異なるテーブルの行を更新して選択します。この場合、selectによって読み取られるテーブルは、実験中にまったく変更されませんでした。

各セットは、シェルスクリプトを使用して2回実行されました(したがって、タイミングは私の元の質問のタイミングよりも遅くなります)。1つは通常の状態で、もう1つは次のコマンドを実行した後です。

tc qdisc replace dev wlan0 root handle 1:0 netem delay 200ms

上記のコマンドは、wlan0を介してパケットを送信するときに200msの平均遅延を追加します。

まず、上位99%の更新と選択、および下位1%の更新と選択の平均時間を示します。

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

明らかなように、I / Oパフォーマンスが非常に低い場合でも、MySQLはほとんどのクエリを非常に高速に実行できます。しかし、私が最も懸念しているのは最悪のケースです。ここに、最も遅い10個のクエリを示す別の表を示します。「u」はそれが更新であったことを意味し、「s」は選択を意味します。

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

結論:

  1. I / Oのパフォーマンスが悪いと、MySQLのクロールが遅くなる可能性があります。理由時期は明確ではありませんが、実際に発生します。

  2. 速度低下は選択と更新の両方に適用され、更新はさらに苦しみます。

  3. 上記のUS2MIDから明らかなように、何らかの理由で、変更に関与しておらず、最近入力されたテーブルでの選択も遅くなりました。

  4. mentatkgsによって提案されたテストケースに関しては、同じ行ではなく異なる行を更新することは少しは役立つようですが、問題は解決しません。

私は、そのような遅延を許容するようにソフトウェアを適応させるか、別のプロバイダーに移動しようとするだろうと思います。専用サーバーを借りるのは、このプロジェクトには高額です。

コメントありがとうございます。

于 2012-03-14T03:44:35.873 に答える
1

クラウドでVPSをホストしているため、完全に制御できない問題が発生している可能性があります。

VPSは、VPSを実行するホストサーバーの気まぐれの影響を受けます。たとえば、Rackspace CloudでのCPUサイクルの優先度は、VPSのサイズに基づいて重み付けされます。VPSが大きいほど、アプリがスムーズに実行される可能性が高くなります。使用しているホストに大きなVPSがある場合は、加重バーストが原因である可能性があります。言うのはかなり難しいです。

これを自分のマシンでローカルに実行してみましたか?独自のシステムで完全に実行され、保証されたパフォーマンスが必要な場合は、専用サーバーに移動するのが最善の策です。

于 2012-03-13T06:38:57.283 に答える
1

VPS関連のIOの問題があります。MySQLのせいではありません。

万が一、AmazonでElastic Block Storeを使用していますか、それともRDSを使用していますか?どちらもリモートストレージとIPプロトコルレイヤーを使用してストレージと通信します。彼らは時々厄介な遅れをとることがあります。

于 2012-03-13T17:53:31.103 に答える
0

質問1)はい。

それを確認するには、2つのアプリを作成します。

テストケース1:これをすべてのminutoで数時間行います

UPDATE `projects` SET `ring` = 5 WHERE `id` = 1
UPDATE `projects` SET `ring` = 6 WHERE `id` = 1

テストケース2:これを数時間毎分実行します

UPDATE `projects` SET `ring` = 7 WHERE `id` = 1
UPDATE `projects` SET `ring` = 8 WHERE `id` = 2

テストケース1には遅延が必要ですが、テストケース2には遅延がありません。

質問2)noSQLデータベースを使用します。

于 2012-03-12T21:15:17.453 に答える