質問: Webサイト上のとあるスクリプトを実行すると以下のエラーが出ます。 (このスクリプトはMySQLからデータを引張って、画面に表示orダウンロードする処理を行なっています。) ``` Allowed memory size of X bytes exhausted (tried to allocate Y bytes) /hogehoge.php ``` 上記のエラーについて、php.iniのmemory_limitを十分に大きいX bytes以上の値にすると問題なく実行することができます。(Xの値は1GBくらいです。) しかしながら、php.iniのmemory_limitを1GBなど大きな値にすると接続数の増加に伴いサーバ側のメモリが枯渇してしまう恐れがあると考えています。 通常のWeb閲覧ですと1つのコネクションあたりの使用メモリは20~30MBくらいで、メモリの最大値をmemory_limitの1GBにしても問題ないような気もします。 (全員が一斉に上記のスクリプトを実行したらメモリが枯渇してしまいますが...) memory_limitは、一つのコネクション(一人の利用者、接続者)の上限値であって、その利用者が実際に使用するメモリのみが使われ、コネクション確立時には、memory_limitで設定した上限値が予め確保はされない(使う時だけ使う分のみ確保される)という認識であっていますでしょうか。 その場合、memory_limitに1GBなど大きな値を設定しても問題ないでしょうか。 また、上記のエラーですが、この X bytesはどこの設定の値を参照しているのでしょうか。 現状のmemory_limitはX bytesより十分小さい値(128MB)です。 上記、スクリプトの修正や改良はできないため、メモリ周りでWebサーバ(apache, php, mysql)のチューニング方法、考え方等を教えていただけますと幸いです。 よろしくお願いいたします。
回答: > > memory_limitで設定した上限値が予め確保はされない(使う時だけ使う分のみ確保される)という認識であっていますでしょうか。 > > > > > スクリプトが確保できる最大メモリをバイト数で指定します > > > とありますので、その認識で間違いないでしょう。実際には-1みたいに無制限もつけられます。 > > memory_limitに1GBなど大きな値を設定しても問題ないでしょうか > > > 大きな値を設定しても問題ないかどうかは、PHPの仕様上は無制限が設定できるので、いくらでも大きくできるでしょう。 ただし、実際は環境によって、大量にメモリを消化するスクリプトがどれぐらいの発生率なのか? 実際のサーバでメモリオーバーした際にはOSからプロセスがkillされるかハングアップすることになるのでそのリスクに耐えられるのか? そのリスクによってどれだけ、プロダクトやプロジェクトに被害がもたらされるか? ということを検討する必要があります。 よってプロジェクトのリスク管理の話になりますので改めて要件を確認してみてください。 > > 上記のエラーですが、この X bytesはどこの設定の値を参照しているのでしょうか。 > > 現状のmemory_limitはX bytesより十分小さい値(128MB)です。 > > > 基本的にmemory_limitの設定を反映する形になっています。 ただし設定箇所はいくつか候補があって php.ini もしくは .htaccess もしくは phpスクリプト内(ini_set) それらのいずれかを見逃している可能性があります。 本来はスクリプトの修正で対応できることが最短で効果的です。 それが難しい場合は、チューニングになるのですが、それでもあくまで「チューニング」なので限界は来ます。 そうなるとスケールアップとスケールアウトの対応になってくるでしょう。 スケールアップは単純にメモリをたくさん積む。 スケールアウトは重くなるスクリプトやアクセスについては、ロードバランサーで別のサーバを用意してメモリ増強したサーバに流す。 といった感じですね。コストもかかる対応なのでスクリプト修正のコストとの比較になりますね。