Azure函数内存不足异常。

3

我正在从 Blob 中读取 PDF 文件并使用 Azure Function 进行一些操作。当 PDF 大小为 1.5GB(或更大)时,我的 Azure Function 在代码命中以下命令后立即因内存不足而失败。

var ms = new MemoryStream();
log.LogInformation("Converting this File to memorystream : " + blob.Uri);
blob.DownloadToStream(ms);  //Failes HERE.

我尝试将计划切换到EP3(14 GB内存+840 ACU),但问题仍然相同。我需要更改其他配置吗?如何处理这个问题。

Microsoft.Azure.Storage.StorageException: Exception of type 'System.OutOfMemoryException' was thrown.
 ---> System.OutOfMemoryException: Exception of type 'System.OutOfMemoryException' was thrown.
   at System.IO.MemoryStream.set_Capacity(Int32 value)
   at System.IO.MemoryStream.EnsureCapacity(Int32 value)
   at System.IO.MemoryStream.Write(Byte[] buffer, Int32 offset, Int32 count)
   at System.IO.MemoryStream.WriteAsync(Byte[] buffer, Int32 offset, Int32 count, CancellationToken cancellationToken)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.Azure.Storage.Core.Util.AsyncStreamCopier`1.StartCopyStreamAsyncHelper(Nullable`1 copyLength, Nullable`1 maxLength, CancellationToken token)
   at Microsoft.Azure.Storage.Core.Util.AsyncStreamCopier`1.StartCopyStreamAsync(Nullable`1 copyLength, Nullable`1 maxLength, CancellationToken cancellationToken)
   at Microsoft.Azure.Storage.Core.Executor.Executor.ExecuteAsync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token)
   --- End of inner exception stack trace ---
   at Microsoft.Azure.Storage.Core.Executor.Executor.ExecuteAsync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext, CancellationToken token)
   at Microsoft.Azure.Storage.Core.Executor.Executor.<>c__DisplayClass0_0`1.<ExecuteSync>b__0()
   at Microsoft.Azure.Storage.Core.Util.CommonUtility.RunWithoutSynchronizationContext[T](Func`1 actionToRun)
   at Microsoft.Azure.Storage.Core.Executor.Executor.ExecuteSync[T](RESTCommand`1 cmd, IRetryPolicy policy, OperationContext operationContext)
   at Microsoft.Azure.Storage.Blob.CloudBlob.DownloadRangeToStream(Stream target, Nullable`1 offset, Nullable`1 length, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext)
   at Microsoft.Azure.Storage.Blob.CloudBlob.DownloadToStream(Stream target, AccessCondition accessCondition, BlobRequestOptions options, OperationContext operationContext)

当你完成加载流后,你会用它做什么?大多数基于流的API都是流式的,不需要先读取整个内容。除非你需要在底层字节数组上进行操作,否则你可以直接读取CloudBlob.OpenRead返回的流。 - Tom W
我们将其制作为PDF文档,以便在需要时进行进一步的拆分或图像创建。 - lokesh
2个回答

0

这篇博客似乎已经找到了问题所在 - MemoryStream需要一个int32来设置其容量,没有使用更大数字的选项。我无法完全将int32.MaxValue(2147483647)的值与指定的大小(1.5GiB以字节为单位为1610612736字节)相一致,但它似乎足够接近成为罪魁祸首。该博客提出了一种解决方法,用于将大容量内容写入Blob存储,但我不认为这对您的用例有用。

如果您确实需要使用MemoryStream来满足您正在使用的库的需求,则无法处理如此大的文件。


0

我正在阅读CSV文件,所以不确定这是否直接适用。 然而,最初我尝试做你那里正在做的事情,将整个blob全部提取出来,但遇到了这个问题。 通过使用类似于以下的内容,我能够在我们的过程中获得更多的信息:

public async Task<string> ReadCsvRowRawAsync()
{
   string currentRowRaw = await Reader.ReadLineAsync();
   if (Reader.EndOfStream)
   {
       EndOfStream = true;
   }
   return currentRowRaw;
}

逐行处理只允许在内存中存储一小段。

我仍然会遇到问题,但只有在最大的文件上。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接