アマゾンの検索をするとき、PHPでバッチ処理を書いた。PHPで大量のリクエストを発行してAmazonECS結果を見ていた。ふとメモリ消費量を見る。ちびりそうになる。メモリ消費量が上昇し続ける。unset()をしているが、メモリの消費量は変化しない。
立ち止まって考える。当たり前じゃないか。PHPはApacheのリクエスト毎に起動して、リクエスト終了時にメモリから全部消去される。バッチ処理が終わらないとメモリ解放されないのかね。処理が長くなれば不利じゃないか。繰り返し処理でメモリを再利用しない。なら、バッチの大量データを処理に不向きか。一応はコマンドラインで動きます程度なのね。
もし、PHPバッチ処理をするなら、バッチ処理の細切れな生成、消去を短時間に繰り返すしかないのね。
バッチ処理とは大量のデータを夜間などに処理する事。そう記憶している。他スクリプト言語も同じか。元もとメモリ管理が出来ないのだ。もし1時間以上かかるなら、1分のを60回起動するべきか。
ちなみに、PHP 5.1.2でテストしている。PHP 5.2.xからはメモリについて --enable-malloc-mm が提供されている。memory_get_usage()を使って細かく調べられる。そのうち試してみたい。
処理する量が大きく違う
- バッチはリクエスト処理の1000倍分繰り返す。
と言うことがある。だからメモリはなかなか解放されず処理が遅くなる。
解決はこうする
- バッチAは1回の処理をする。
- バッチBはバッチAを1000回起動する。
サンプルコード
バッチA
<?php $a = new Hoge("last"); $a->setAAA(true); $a->save #重い処理
バッチB
<?php foreach( range(1,1000) as $a ) { sysmtem('php batchA'); #バッチAを起動する。 }
こうすればメモリ消費量は小さくてスワップしないから速く終る。