我正在使用PHP的AWS 2.3.2 SDK尝试从S3中使用它们的流包装器拉下一个大文件(〜4g),这应该允许我使用fopen/fwrite将文件写入磁盘,而不是缓冲到内存中。Heroku内存错误与PHP和从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 heroku [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 Fault。
我也尝试使用cURL和CURLOPT_FILE选项下载文件直接写入磁盘,并且内存不足。奇怪的是根据top
我的php实例正在使用223m的内存,所以甚至没有允许的一半512.
任何人有任何想法?我从php 5.4.17 cli运行这个测试。
也尝试了PHP复制命令,并使用fflush($ fp)来刷新写入缓冲区。这不应该耗尽内存 – bonez
你可以改变为'rb'和'wb'以二进制模式读写文件吗?此外,这不应该改变任何东西,但只是为了确保 - 如果您使用临时变量在读写之间保存数据,您会得到相同的结果吗? – culix
试过,并没有改变任何东西...也要清楚:从命令行 - $ curl -O http://test.s3.amazonaws.com/file.zip也导致内存错误,我认为是问题。这可能是一个虚假的错误,我不知道,我在Heroku中有一个支持请求 – bonez