web-dev-qa-db-ja.com

ApacheとPHPでメモリリークを調査する方法は?

財務モデリングを実行する重いDrupal Webサイトを実行しています。Apacheプロセスの数が増える一方で、Apacheが使用するメモリが時間とともに増加するという事実を考えると、なんらかのメモリリークが発生しているようです安定したまま:

enter image description here

enter image description here

/etc/init.d/httpd reloadを発行するたびにメモリ使用量が低下するため(上​​記のスクリーンショットと以下のCLI出力を参照)、Apache/PHPからメモリの問題が発生していることがわかります。

Httpdのリロード前

 $ free 
 cached used cached shared buffers cached 
 Mem:49447692 45926468 3521224 0 191100 22609728 
-/ + buffers/cache:23125640 26322052 
スワップ:2097144 536552 1560592 

Httpdのリロード後

 $ free 
 cached used cached shared buffers cached 
 Mem:49447692 28905752 20541940 0 191360 22598428 
-/ + buffers/cache:6115964 43331728 
スワップ:2097144 536552 1560592 

各ApacheスレッドにはPHP memory_limit 512MBが割り当てられており、メモリ使用量が多いために要求の量が少ないことがわかります。max_execution_timeが120秒でスレッドを終了する必要があります。どの実行に時間がかかるか、したがって、メモリ使用量の継続的な増加を防ぐ必要があります。

Q:このメモリリークの原因を調査するにはどうすればよいですか?

理想的には、開発チームを煩わせることなく、システムで実行できるトラブルシューティングの手順を探しています。

追加情報:

OS: RHEL 5.6
PHP: 5.3
Drupal: 6.x
MySQL: 5.6

参考までに、私たちは個別に調査しているスワッピングの問題を認識しており、スワッピングが発生し始める前に観察したメモリリークとは何の関係もありません。

17
Max

/etc/init.d/httpdリロードを発行するたびにメモリ使用量が低下するため、メモリの問題がApache/PHPに起因していることがわかります

いいえ-それは単にWebトラフィックに関連していることを意味します。あなたはボックス上でmysqlを実行していると言ってきました-おそらくWebサーバーのデータを管理している-これが原因である可能性も同じくらい簡単です。あなたが言及していない他のサービスと同様に、あなたのウェブスタックが使用します。

各ApacheスレッドにはPHP 512MBのmemory_limitが割り当てられています。

いいえ、ありません。平均7台、最大25台のビジーサーバーを報告していますが、メモリグラフは約25Gbの差分を示しています。

本当に基本的なHTTPチューニングからやり直す必要があります-常に256のhttpdsを実行しているようですが、ピーク使用量は25です-これは単なるばかげています。

実行に時間がかかっているスレッドを終了する120秒のmax_execution_time

いいえ-実行スレッドがPHPインタープリター内にある場合のみ-PHPがブロックされている場合.

財務モデリングを実行する

(はぁ)

Apacheの構成方法、スレッド化またはプリフォークの詳細、どのバージョン、どのようにPHPが呼び出されるか(モジュール、cgi、fastcgi))、使用しているかどうかの詳細を提供すると役立つでしょうストアドプロシージャを使用するかどうかに関係なく、永続的な接続。

Mysqlを別のマシンに移動することから始め、永続的な接続の使用を停止することをお勧めします(現在使用している場合)。メモリ制限muchを低く設定し、スクリプトごとにこれをオーバーライドします。循環参照ガベージコレクタがインストールおよび設定されていることを確認してください。

11
symcbean

あなたはおそらくあなたの問題を今までに解決したでしょう。サーバーがスワッピング/スラッシングしないようにするための暫定的な措置として、cronから次のコマンドを1時間ごとに実行します。

#!/bin/sh 
sync; echo 3 > /proc/sys/vm/drop_caches

これが解決策であると言っているのではなく、メモリリークの実際の原因を調査するときに、物事を実行し続け、ダウンタイムを最小限に抑える方法にすぎません。

詳細については、こちらをご覧ください。

http://www.tecmint.com/clear-ram-memory-cache-buffer-and-swap-space-on-linux/

2
patrick

どうやらこれがPHPの動作方法です。オブジェクトを割り当てている長いループを実行していて、参照を介してそれらを渡しているかどうかを誰が知っているのかを考えると、対処する唯一の方法は、各PHPプロセスを停止するためのNリクエスト。 PHPをCGIとして実行すると、すべてのリクエストで再生成が行われるため、メモリリークは発生せず、パフォーマンスの低下はそれほど大きくない可能性があります。 fast-cgiを実行することもできます。 1000リクエストごとにphp-fcgiプロセスが強制終了され、メモリが解放されます。ここでもメモリリークはありません。 PHPをモジュールmod_phpとして実行する場合、httpd.confでmaxrequestsを設定して、それが役立つかどうかを確認することができます。私はセットアップしようとします10-それが機能する場合、パフォーマンスの低下はそれほど大きくありませんが、250のhttpdがすべて使用されているときの大きなスパイクの下でも、メモリリークは発生しないはずです(10 * 250 = 2500-各10MBのメモリ使用量は25GB-したがって、128GBがない場合はRAMプロセスのhttpd数を50に下げるなどしてみてください。

1
Andrew Smith