なぜ Apache が暴走して MySQL を殺してしまうのでしょうか?

なぜ Apache が暴走して MySQL を殺してしまうのでしょうか?

ここ数日、Apache が制御不能になり、MySQL が 2 回クラッシュしました。これは、phpBB フォーラムも含まれている WordPress ウェブサイトを移行したときに始まりました。

私はサーバー管理の経験があまりないので、問題の原因を特定するのは非常に困難でした。MySQL がダウンしていることに気付いたとき、TOP を実行したところ、システム負荷が 98.00 に急上昇しました。サーバーは 10 個の V-HOST を実行しており、そのすべてが十分な量のトラフィックを受信して​​いるため、明らかに多くの apache-2 プロセスが実行されていることがわかりました。

サーバーの高負荷状態は 10 分間続き、その後通常の状態に戻りました。この時点では、ネットワーク トラフィックの急増は見られませんでした。

残念ながら、MySQL エラー ログは無効になっています (現在は再度有効になっています) ので、手がかりはありません。ただし、Apache がすべてのリソースを消費していたため、MySQL プロセス ID が強制終了されたことは間違いありません。

私の質問は次のとおりです:

次回これが発生したとき、システム負荷の急増の原因をどのように特定すればよいでしょうか? PHP スクリプトが異常をきたしたのでしょうか? DDOS 攻撃なのでしょうか?

MySQL がクラッシュしたときに自動的に再起動する方法はありますか?

をインストールしましたhtop。これは よりも便利でしょうかtop?

私のサーバーの統計は次のとおりです:

m1.xlarge (8 ECUs, 4 vCPUs, 15 GiB memory, 4 x 420 GiB Storage Capacity)
Ubuntu Server 12.04.3 LTS 

答え1

MySQL はまだ何もログに記録しない可能性があります。これは、Apache の子プロセスによるシステム メモリの負荷が原因で、システムによって MySQL が突然強制終了されている可能性が考えられます。/var/log/syslog にこの痕跡が残っているはずです。

MySQL はクラッシュまたは強制終了時に再起動を試みるはずですが、十分なメモリが利用できない限り、再起動は実行できません... また、この 2 回目の失敗は、mysqld_safe では「クラッシュ」ではなく「起動拒否」とみなされるため、再試行は続行されません。 失敗した再起動の試みは、管理者によって「クラッシュ」と誤解されることがよくあります。これは、元の失敗の性質が、MySQL エラー ログ内の見落とされやすいメッセージの背後に隠れているためです。

mysqld_safe Number of processes running now: 0

見るInnoDB クラッシュ事後分析あなたの状況と似ているのではないかと思います。

「なぜ」に対する一見単純な答えは、Apache と MySQL、負荷、現在の構成により、マシンに十分なメモリがないこと、そしてトラフィック負荷に関連する何らかの転換点がこの状態を引き起こすことです。

Apache は、子プロセスから各同時ブラウザ リクエストを処理するため、同時接続数が増えると、子の数も増えます。同時接続数の増加の原因を実際に把握できるように、まず Apache 構成でこの値を制限する必要があります。単にトラフィックが急増しているだけなのでしょうか。何らかのサービス拒否でしょうか。実行時間が長すぎるためにリクエストを遅らせる DB クエリでしょうか。最適化が必要な何かでしょうか。

http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxclients

同時実行可能な Apache プロセスを制限すると、この問題を回避できるはずですが、誤解のないように言っておくと、これが完全な解決策であると考えるのは単純すぎるので、そう言いたいわけではありません。プロセスが妥当なレベル、または少なくともより安全なレベルに制限されたら、実際に何が起こっているのか特定する作業に進むことができます。(Apache には他の制限制御もありますが、それは私の専門分野ではありません。)

「ベスト プラクティス」は、もちろん、アプリケーションがデータベースを終了できないように、異なるハードウェアでデータベースを実行することです。表面的には、1 台のマシンを共有して「最大限に活用する」方が効率的であるように見えますが、これは誤った節約です。一般的なワークロードでは、MySQL が使用するメモリの大部分は起動時に割り当てられ、MySQL Server が稼働している間保持されます。CPU の需要は、MySQL と Apache のピーク時間を共有する可能性が高いです。なぜなら、これらは最終的に同じ負荷を処理するからです。実際には、1 台の m1.xlarge マシンではなく 2 台の m1.large マシンを使用する方がよいかもしれません。小さい方のマシンは大きい方のマシンのちょうど半分の価格なので、コストは同じです... すでに追加割引を前払いしていたとしても、この変化は達成できる

答え2

確認すべき点がいくつかあります:

- /var/log/messages を確認してください。使用できるメモリがなくなった場合、oomkiller は mysql プロセスを強制終了できます。free -lm (キャッシュなし) で ram を確認してください。

- Apache を prefork mpm とともに使用する場合: プロセスの数を確認します。Apache が (負荷の高い作業中に) mysql へのリンクを使用して多数のプロセスをスタックすると、レイテンシとメモリ使用量が急速に増加する可能性があります。

-mysqlによって起動されたスレッドの数を確認しますグローバルステータスを表示: threads_cached、threads_created、threads_running をチェックすることが重要です (threads_created は 0 に近い値である必要があります)。

-Mysql によって使用される RAM を確認します。

答え3

実装を検討することもできますCPUセットそして、mysql 用のリソースを予約します。これは、これらのサービスを異なるハードウェアで実行することに最も近い方法ですが、単一のサーバーを維持する利点も得られます。

関連情報