我们正在开发需要使用 Azure 作为文件内容存储的文档微服务。Azure Block Blob 似乎是一个合理的选择。文档服务的堆限制为 512MB ( -Xmx512m
)。
我没有成功地使用有限的堆来上传流文件azure-storage-blob:12.10.0-beta.1
(也在 上测试过12.9.0
)。
尝试了以下方法:
- 使用从文档中复制粘贴
BlockBlobClient
BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient("file").getBlockBlobClient();
File file = new File("file");
try (InputStream dataStream = new FileInputStream(file)) {
blockBlobClient.upload(dataStream, file.length(), true /* overwrite file */);
}
结果: java.io.IOException: mark/reset not supported
- SDK 尝试使用标记/重置,即使文件输入流报告此功能不受支持。
- 添加
BufferedInputStream
以减轻标记/重置问题(根据建议):
BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient("file").getBlockBlobClient();
File file = new File("file");
try (InputStream dataStream = new BufferedInputStream(new FileInputStream(file))) {
blockBlobClient.upload(dataStream, file.length(), true /* overwrite file */);
}
结果: java.lang.OutOfMemoryError: Java heap space
。我假设 SDK 试图将所有 1.17GB 的文件内容加载到内存中。
- 替换
BlockBlobClient
和BlobClient
删除堆大小限制 (-Xmx512m
):
BlobClient blobClient = blobContainerClient.getBlobClient("file");
File file = new File("file");
try (InputStream dataStream = new FileInputStream(file)) {
blobClient.upload(dataStream, file.length(), true /* overwrite file */);
}
结果:使用了 1.5GB 的堆内存,所有文件内容都加载到内存中 + 在 Reactor 一侧进行了一些缓冲
- 通过以下方式切换到流式传输
BlobOutputStream
:
long blockSize = DataSize.ofMegabytes(4L).toBytes();
BlockBlobClient blockBlobClient = blobContainerClient.getBlobClient("file").getBlockBlobClient();
// create / erase blob
blockBlobClient.commitBlockList(List.of(), true);
BlockBlobOutputStreamOptions options = (new BlockBlobOutputStreamOptions()).setParallelTransferOptions(
(new ParallelTransferOptions()).setBlockSizeLong(blockSize).setMaxConcurrency(1).setMaxSingleUploadSizeLong(blockSize));
try (InputStream is = new FileInputStream("file")) {
try (OutputStream os = blockBlobClient.getBlobOutputStream(options)) {
IOUtils.copy(is, os); // uses 8KB buffer
}
}
结果:文件在上传过程中损坏。Azure 门户网站显示 1.09GB 而不是预期的 1.17GB。从 Azure Web 门户手动下载文件可确认文件内容在上传期间已损坏。内存占用显着减少,但文件损坏是个大问题。
问题:无法提供内存占用小的有效上传/下载解决方案
任何帮助将不胜感激!