【问题标题】:TransferManager vs PutRequestObject in AmazonS3AmazonS3 中的 TransferManager 与 PutRequestObject
【发布时间】:2020-02-13 21:34:12
【问题描述】:

我对对象单一上传和分段上传感到困惑。两者都在消耗相同的时间。我的代码如下:

File file = new File("D:\\AmazonS3\\aws-java-sdk-1.8.3\\lib\\aws-java-sdk-1.8.3-javadoc.jar");
FileInputStream fis = new FileInputStream(file);

String keyName = System.currentTimeMillis()+"_aws-java-sdk-1.8.3-javadoc.jar";

ObjectMetadata metaData = new ObjectMetadata();
metaData.addUserMetadata("test","TEST");
//Object single upload
PutObjectRequest putobejcObjectRequest = new PutObjectRequest(BUCKET_NAME, keyName, fis,metaData);
putobejcObjectRequest.setMetadata(metaData);
s3client.putObject(putobejcObjectRequest);

//Object multipart upload
TransferManagerConfiguration configuration = new TransferManagerConfiguration();
    configuration.setMultipartUploadThreshold(5*com.amazonaws.services.s3.internal.Constants.MB);
TransferManager transferManager = new TransferManager(s3client);
transferManager.setConfiguration(configuration);

Upload upload = transferManager.upload(BUCKET_NAME, keyName, fis,metaData);
upload.waitForCompletion();
transferManager.shutdownNow();

请帮帮我,我的代码有什么问题吗。

【问题讨论】:

    标签: amazon-s3


    【解决方案1】:

    我遇到了同样的问题,并且发现(通过检查 SDK 代码)传输管理器仅在您传递文件而不是 InputStream 时才会使用并行部分上传。

    查看来自 sdk(版本 1.8.9)的决策代码:

    if (TransferManagerUtils.isUploadParallelizable(putObjectRequest, isUsingEncryption)) {
       captureUploadStateIfPossible();
       uploadPartsInParallel(requestFactory, multipartUploadId);
       return null;
    } else {
       return uploadPartsInSeries(requestFactory);
    }
    

    uploadParallelizable 在哪里:

    // Each uploaded part in an encrypted upload depends on the encryption context
    // from the previous upload, so we cannot parallelize encrypted upload parts.
    if (isUsingEncryption) return false;
    
    // Otherwise, if there's a file, we can process the uploads concurrently.
    return (getRequestFile(putObjectRequest) != null);
    

    因此,如果您想利用部分并行上传的优势,请将文件传递给 TransferManager。

    【讨论】:

    • 这是否意味着如果我想上传一个 >5GB 的加密文件,使用 SDK 是不可能的?由于 TransferManager 不支持加密,使用s3client.putObject 处理这么大的文件会导致堆空间不足...
    • 如果你有你的内容作为文件,你不会用完堆空间,因为它不会被加载到内存中
    【解决方案2】:

    从流上传选项时,调用者必须提供 通过内容长度字段在流中的选项 对象元数据参数。如果没有指定内容长度 输入流,然后 TransferManager 将尝试缓冲所有 在内存中流式传输内容并作为传统方式上传选项, 单部分上传。因为整个流内容必须是 缓冲在内存中,这可能非常昂贵,应该避免 尽可能。

    来源:https://docs.aws.amazon.com/AWSJavaSDK/latest/javadoc/com/amazonaws/services/s3/transfer/TransferManager.html#upload-java.lang.String-java.lang.String-java.io.InputStream-com.amazonaws.services.s3.model.ObjectMetadata-

    【讨论】:

      猜你喜欢
      • 2016-02-09
      • 1970-01-01
      • 2012-01-11
      • 1970-01-01
      • 1970-01-01
      • 2012-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多