私が現在取り組んでいるシステムでは、大量のデータを配列にロードして、ソート/集約/なんでもするプロセスがあります。このプロセスではメモリ使用量を最適化する必要があることは知っていますが、短期的には動作する必要があります。
配列に読み込まれたデータの量を考えると、メモリの制限に達し続けます。それは数回増加していますが、それを増やすことは一般的に悪い考えになるポイントがあるのだろうか?それとものみマシンのRAMの大きさの問題ですか?
マシンには2GBのRAMがあり、memory_limitは現在1.5GBに設定されています。 RAMをマシンに簡単に追加できます(とにかく追加します)。
他の人はこの種の問題に遭遇しましたか?そして解決策は何でしたか?
PHPサーバーWebページへのApacheモジュールとして実行するmemory_limit
の構成では、マシン上で同時に使用できるApacheプロセスの数を考慮する必要があります。 ApacheのMaxClients
構成オプション。
MaxClients
が100で、2,000 MBまたはRAMがある場合、20 MB *(20 MB * 100クライアント= 2 GBまたはRAM、つまり合計量)を超えて使用しないでください。サーバーのメモリ))*のmemory_limit値。
そして、これはおそらく、MySQL、システム自体など、同じサーバー上で実行されている他のものが存在することを考慮せずに...そして、Apacheはおそらくすでにいくつかのメモリを使用しています。
または、これは「最悪のシナリオ」でもあり、各PHPページが使用可能な最大メモリ量を使用していることを考慮します。
あなたの場合、1つのジョブだけにこのような大量のメモリが必要な場合、Apacheモジュールとして実行されているPḦPのmemory_limit
を増やしません。
代わりに、コマンドライン(またはcronジョブを介して)からそのジョブを起動し、この1つだけのケースでより高いmemory_limit
を具体的に指定します。
これは、次のようにphpの-d
オプションを使用して実行できます。
$ php -d memory_limit=1GB temp.php
string(3) "1GB"
この場合、temp.phpには次のもののみが含まれていると考えてください。
var_dump(ini_get('memory_limit'));
私の意見では、これはApacheのPHPモジュールのmemory_limitを増やすよりもはるかに安全です-そしてそれは私が大規模なデータセットまたは最適化できないいくつかの本当に重いものがあるときに私が通常行うことですまたはページネーション。
PHP CLIの実行に複数の値を定義する必要がある場合、デフォルトのphp.iniの代わりに、-c
オプション:
php -c /etc/phpcli.ini temp.php
そのように、あなたが持っている:
/etc/php.ini
、Apache用、低memory_limit
、低max_execution_time
、.../etc/phpcli.ini
は、コマンドラインから実行されるバッチの場合、実質的に制限なしこれにより、バッチを実行できるようになり、Webサイトのセキュリティが確保されます(memory_limit
およびmax_execution_time
はセキュリティ対策です)
それでも、スクリプトを最適化する時間があれば、すべきです;たとえば、大量のデータを処理する必要があるような状況では、ページネーションは必須です;-)
データセットを小さな部分に分割して、一度に1つの部分だけを処理しようとしましたか?
ディスクファイルからデータをフェッチする場合、 fread()
関数を使用して小さなチャンクをロードするか、一部の 並べ替えられていないdbクエリ を使用できますデータベースの。
私はv3.somethingからPHPをチェックしていませんが、クラウドコンピューティングの形式を使用することもできます。1GBデータセットは複数のマシンで処理するのに十分な大きさのようです。
スクリプトに修正が必要なメモリの問題があり、短期的なソリューションのみを探していることを知っている場合、 プロファイリングについて およびメモリの問題を解決する方法については説明しません。 。あなたはそれに到達しようとしているように聞こえます。
だから、あなたが心に留めておく必要がある主なものは次のとおりだと思います:
PHPは、システムの小さなコンポーネントの1つにすぎません。膨大な量のRAMを使い果たしてしまうと、他のプロセスが悪影響を受け、スクリプト自体に影響を与える可能性があります。特に、データベースから大量のデータを引き出す場合、DBMSはクエリの結果セットを作成するために大量のメモリを必要とする場合があります。簡単な解決策として、実行中のクエリを特定し、できるだけ早く結果を解放して、長時間のジョブ実行のためにより多くのメモリを確保することができます。
OSの機能に関しては、実行している可能性が高い32ビットシステムは、特別な処理なしで最大4GBのRAMのみに対応できることに注意してください。多くの場合、制限は一部のWindowsチップセットおよび構成では、4GB以上の物理的にインストールされたシステムであっても、システムで実際に使用できるのは3GB未満である場合があります。
あなたはメモリ制限を数回増やしたと言うので、明らかにこの仕事はますます範囲が拡大しています。最大1.5Gbの場合、さらに2GbをインストールしてもRAMは短い猶予期間のように聞こえます。
他の人はこの種の問題に遭遇しましたか?そして、解決策は何でしたか?
たぶん、あなたはおそらく唯一の本当の解決策が壊れて、すぐにスクリプトを最適化するために時間を費やすことであることを知っていると思うと思います。