Google云端存储 - 将大对象重写为“近线”存储桶时出现SocketTimeoutException

时间:2015-05-12 10:23:49

标签: rewrite google-cloud-storage socket-timeout-exception

环境:
Java客户端(“google-api-services-storage”,“v1-rev33-1.20.0”)使用JSON API(com.google.api.services.storage.Storage类)。

目标:
使用Java客户端将大对象从“标准”移动到“近线”桶(文件大小为512 MB)。

步骤:
使用"rewrite" API方法。

问题:
我在20秒内收到SocketTimeoutException。

调查:
当我使用从“标准”存储桶重写到同一对象的另一个“标准”存储桶时,相同的代码工作正常 我还尝试了APIs Explorer并创建了一个请求,将对象从“标准”重写为“近线”桶。服务器在大约27秒内响应,响应中的“totalBytesRewritten”属性大约是文件大小的一半。如何获得和处理这种反应?
文件说:
“如果源和目标是不同的位置和/或存储类,则重写方法可能需要多次调用。”

我的代码(Java):

final Storage.Objects.Rewrite rewriteRequest = storage.objects().rewrite(
       STANDARD_BUCKET_NAME,
       SOURCE_OBJECT_PATH,
       NEARLINE_BUCKET_NAME,
       TARGET_OBJECT_PATH,
       null // no metadata overriding
);

rewriteRequest.execute();

请帮忙。

1 个答案:

答案 0 :(得分:0)

根据documentation,如果文件被拆分为块,则应该使用重写的第一个响应中返回的'rewriteToken'再次调用rewrite。操作将恢复,再处理一大块数据。这应该重复,直到响应有getDone()== true。

我对java api的实现:

private void rewriteUntilDone(final String sourceBucket, final String sourceKey,
                              final String destBucket,  final String destKey) throws IOException {
    rewriteUntilDone(sourceBucket, sourceKey, destBucket, destKey, null);
}

private void rewriteUntilDone(final String sourceBucket, final String sourceKey,
                              final String destBucket, final String destKey,
                              @Nullable final String rewriteToken)
        throws IOException {

    Storage.Objects.Rewrite rewrite = googleStorage.objects().rewrite(sourceBucket, sourceKey, destBucket, destKey, null);
    if (rewriteToken != null) {
        rewrite.setRewriteToken(rewriteToken);
    }
    RewriteResponse rewriteResponse = rewrite.execute();

    if (!rewriteResponse.getDone()) {
        String rewriteToken2 = rewriteResponse.getRewriteToken();
        BigInteger totalBytesRewritten = rewriteResponse.getTotalBytesRewritten();
        log.debug("Rewriting not finished, bytes completed: {}. Calling rewrite again with token {}", totalBytesRewritten, rewriteToken2);
        rewriteUntilDone(sourceBucket, sourceKey, destBucket, destKey, rewriteToken2);
    }
}

编辑: 此外,您可能必须增加读取超时。似乎重写在27秒后响应,但默认的时间是20秒。 Wrap your GoogleCredentials to set the read timeout