【问题标题】:Heroku Memory Error with PHP and reading large file from S3PHP的Heroku内存错误并从S3读取大文件
【发布时间】:2013-08-25 18:14:29
【问题描述】:

我正在使用适用于 PHP 的 AWS 2.3.2 SDK 尝试使用他们的流包装器从 S3 拉下一个大文件(~4g),这应该允许我使用 fopen / fwrite 将文件写入磁盘并不缓冲到内存中。

这里是参考:

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。

我还尝试使用带有 CURLOPT_FILE 选项的 cURL 下载文件以直接写入磁盘,但内存仍然不足。奇怪的是,根据top,我的 php 实例使用了 223m 的内存,所以甚至不到允许的 512 的一半。

有人有什么想法吗?我从 php 5.4.17 cli 运行它来测试。

【问题讨论】:

  • 还尝试了 php copy 命令,并使用 fflush($fp) 刷新写入缓冲区。这不应该耗尽内存
  • 能不能改成rbwb以二进制方式读写文件?此外,这不应该改变任何东西,只是为了确保 - 如果您使用临时变量来保存读取和写入之间的数据,您会得到相同的结果吗?
  • 尝试过不会改变任何东西......还要清楚:从命令行 - $ curl -O test.s3.amazonaws.com/file.zip 也会导致内存错误,我认为这是问题所在。我不知道这可能是一个虚假错误,我有一个 Heroku 支持请求
  • heroku dynos 是否有可能具有最大硬盘驱动器大小并为此抛出 R14s 而不是一些更具体的错误?您能否查询可用硬盘空间并在您的应用程序执行或curl 下载期间观察它,看看错误是否以一致的文件大小发生?
  • 559G 在 /tmp 上可用 .. 当文件达到大约 1 个 gig 时会发生内存错误,所以不确定它是否以某种方式缓冲或什么。 Heroku cli 没有很多诊断工具

标签: php memory heroku amazon-web-services amazon-s3


【解决方案1】:

您是否已经尝试过 2x dyno,那些有 1GB 内存?

您还可以尝试通过在 PHP 中执行 curl 命令来下载文件。这不是最干净的方式,但它会更快/更可靠且内存友好。

exec("curl -O http://test.s3.amazonaws.com/file.zip", $output);

此示例适用于公共 URL。如果您不想公开您的 S3 文件,您始终可以创建一个签名 URL 并将其与 curl 命令结合使用。

【讨论】:

  • 是的,然后我得到 2013-08-23T14:30:06.785538+00:00 heroku[run.7646]: Process running mem=1024M(100.0%) 2013-08-23T14:30 :06.785658+00:00 heroku[run.7646]: 错误 R14(超出内存配额)
  • 也许你应该尝试一下 curl 实现,就像我在上面编辑过的帖子中解释的那样。
  • 尝试了实现和相同的结果:2013-08-23T19:23:29.446439+00:00 heroku[run.2306]: Process running mem=1024M(100.0%) 2013-08-23T19: 23:29.447246+00:00 heroku[run.2306]:错误 R14(超出内存配额)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-09-19
  • 2020-09-06
  • 2020-03-19
相关资源
最近更新 更多