PHP用のAWS 2.3.2 SDKを使用して、ストリームラッパーを使用してS3から大きなファイル(〜4g)をプルダウンしようとしています。 fopen/fwriteを使用してファイルをディスクに書き込み、バッファをメモリに書き込まないでください。ここでHerokuメモリエラーが発生し、S3から大きなファイルを読み込む
は参照です:ここでは
http://docs.aws.amazon.com/aws-sdk-php-2/guide/latest/service-s3.html#downloading-data
は私のコードです:
public function download()
{
$client = S3Client::factory(array(
'key' => getenv('S3_KEY'),
'secret' => getenv('S3_SECRET')
));
$bucket = getenv('S3_BUCKET');
$client->registerStreamWrapper();
try {
error_log("calling download");
// Open a stream in read-only mode
if ($stream = fopen('s3://'.$bucket.'/tmp/'.$this->getOwner()->filename, 'r')) {
// While the stream is still open
if (($fp = @fopen($this->getOwner()->path . '/' . $this->getOwner()->filename, 'w')) !== false){
while (!feof($stream)) {
// Read 1024 bytes from the stream
fwrite($fp, fread($stream, 1024));
}
fclose($fp);
}
// Be sure to close the stream resource when you're done with it
fclose($stream);
}
ファイルのダウンロードが、私は継続的にHerokuのからのエラーメッセージを取得:
2013- 08-22T19:57:59.537740 + 00:00英雄[run.9336]:プロセス実行 MEM = 515M(100.6パーセント)2013-08-22T19:57:59.537972 + 00:00 Herokuの[run.9336]: エラーR14これはまだあると信じて私をリード
を(メモリ割当て制限を超えました)メモリに何らかの形でバッファリングする。 https://github.com/arnaud-lb/php-memory-profilerを使用しようとしましたが、Segフォルトがあります。
私はまた、CURLOPT_FILEオプションを指定してcURLを使用してファイルをダウンロードしようとしましたが、ディスクに直接書き込むためにメモリが不足しています。奇妙なことは、top
によると私のPHPインスタンスは223mのメモリを使用しているので、許可された512の半分でもありません。
他にもアイデアはありますか?私はこれをPHP 5.4.17からテストするために実行しています。
また、php copyコマンドを試して、fflush($ fp)を使って書き込みバッファをフラッシュしてみました。これはメモリを使い果たしてはならない – bonez
バイナリモードでファイルを読み書きする 'rb'と' wb'に変更できますか?また、これは何も変わるべきではありませんが、ただ確実にするために、読み書きの間にデータを保持するために一時変数を使用する場合、同じ結果が得られますか? – culix
それは何も変わっていませんでした...クリアすることもできます:コマンドラインから - $ curl -O http://test.s3.amazonaws.com/file.zipでもメモリエラーが発生すると思います問題です。それは私が知らない間違ったエラーかもしれない、私はHerokuとのサポートリクエストを持っている – bonez