2011-01-15 13 views
15

Próbowałem użyć przykładowego kodu Amazon-SDK (Java) S3TransferProgressSample.java, aby przesłać duże pliki do pamięci Amazon-S3 (also posted here on AWS docs).Problemy podczas przesyłania dużych plików do Amazon S3

Ale gdy próbuję przesłać 11 plików GB, upload jest utknięcie w różnych punktach z komunikatem o błędzie:

Unable to upload file to Amazon S3: Unable to upload part: Unable toexecute HTTP request: Unbuffered entity enclosing request can not be repeated " (attached screenshot). 

Wygląda na to, że po IOException występuje SDK nie jest w stanie ponowić żądanie (patrz poniżej).

Czy ktoś to spotyka? Jaka jest najlepsza praktyka, aby rozwiązać ten problem? Każdy kod jest doceniany.

INFO: Received successful response: 200, AWS Request ID: 
2B66E7669E24DA75<br> Jan 15, 2011 6:44:46 AM 
com.amazonaws.http.HttpClient execute<br> INFO: Sending Request: PUT 
s3.amazonaws.com /test_file_upload/autogenerated.txt Parameters: 
(uploadId: 
    m9MqxzD484Ys1nifnX._IzJBGbCFIoT_zBg0xdd6kkZ4TAtmcG0lXQOE.LeiSEuqn6NjcosIQLXJeKzSnKllmw--, partNumber: 1494,)<br> Jan 15, 2011 6:45:10 AM 
    org.apache.commons.httpclient.HttpMethodDirector executeWithRetry<br> 
    **INFO: I/O exception (java.net.SocketException) caught when processing request: Connection reset by peer: socket write error**<br> 
    Jan 15, 2011 6:45:10 AM 
    org.apache.commons.httpclient.HttpMethodDirector executeWithRetry<br> 
    INFO: Retrying request<br> Jan 15, 2011 6:45:12 AM 
    com.amazonaws.http.HttpClient execute<br> WARNING: Unable to execute 
    HTTP request: Unbuffered entity enclosing request can not be 
    repeated.<br> Jan 15, 2011 6:45:12 AM 
    org.apache.commons.httpclient.HttpMethodDirector executeWithRetry<br> 
    **INFO: I/O exception (java.net.SocketException) caught when processing request: Connection reset by peer: socket write error**<br> 
    Jan 15, 2011 6:45:12 AM 
    org.apache.commons.httpclient.HttpMethodDirector executeWithRetry<br> 
    INFO: Retrying request<br> Jan 15, 2011 6:45:13 AM 
    org.apache.commons.httpclient.HttpMethodDirector executeWithRetry<br> 
    **INFO: I/O exception (java.net.SocketException) caught when processing request: Connection reset by peer: socket write error**<br> 
    Jan 15, 2011 6:45:13 AM 
    org.apache.commons.httpclient.HttpMethodDirector executeWithRetry<br> 
    INFO: Retrying request<br> Jan 15, 2011 6:45:13 AM 
    com.amazonaws.http.HttpClient execute<br> 
    **WARNING: Unable to execute HTTP request: Unbuffered entity enclosing request can not be repeated.**<br> Jan 15, 2011 6:45:14 AM 
    com.amazonaws.http.HttpClient execute<br> WARNING: Unable to execute 
    HTTP request: Unbuffered entity enclosing request can not be 
    repeated.<br> Jan 15, 2011 6:45:14 AM com.amazonaws.http.HttpClient 
    execute<br> WARNING: Unable to execute HTTP request: Unbuffered entity 
    enclosing request can not be repeated.<br> Jan 15, 2011 6:45:14 AM 
    com.amazonaws.http.HttpClient execute<br> WARNING: Unable to execute 
    HTTP request: Unbuffered entity enclosing request can not be 
    repeated.<br> Jan 15, 2011 6:45:15 AM com.amazonaws.http.HttpClient 
    execute<br> WARNING: Unable to execute HTTP request: Unbuffered entity 
    enclosing request can not be repeated.<br> Jan 15, 2011 6:45:16 AM 
    com.amazonaws.http.HttpClient execute<br> WARNING: Unable to execute 
    HTTP request: Unbuffered entity enclosing request can not be 
    repeated.<br> Jan 15, 2011 6:45:16 AM 

com.amazonaws.http.HttpClient 
    execute<br> WARNING: Unable to execute HTTP request: Unbuffered entity 
    enclosing request can not be repeated.<br> Jan 15, 2011 6:45:17 AM 
    com.amazonaws.http.HttpClient execute<br> WARNING: Unable to execute 
    HTTP request: Unbuffered entity enclosing request can not be 
    repeated.<br> Jan 15, 2011 6:45:19 AM com.amazonaws.http.HttpClient 
    execute<br> WARNING: Unable to execute HTTP request: Unbuffered entity 
    enclosing request can not be repeated.<br> Jan 15, 2011 6:45:19 AM 
    com.amazonaws.http.HttpClient execute<br> ....<br> Jan 15, 2011 
    6:45:21 AM com.amazonaws.http.HttpClient handleResponse<br> 
    **INFO: Received successful response: 204, AWS Request ID: E794B8FCA4C3D007**<br> Jan 15, 2011 6:45:21 AM 
    com.amazonaws.http.HttpClient execute<br> ...<br> Jan 15, 2011 6:45:19 
    AM com.amazonaws.http.HttpClient execute<br> INFO: Sending Request: 
    DELETE s3.amazonaws.com /test_file_upload/autogenerated.txt 
    Parameters:<br> ...<br> Jan 15, 2011 6:47:01 AM 
    com.amazonaws.http.HttpClient handleErrorResponse<br> INFO: Received 
    error response: Status Code: 404, AWS Request ID: 0CE25DFE767CC595, 
    AWS Error Code: NoSuchUpload, AWS Error Message: The specified upload 
    does not exist. The upload ID may be invalid, or the upload may have 
    been aborted or completed.<br> 

Odpowiedz

17

Spróbuj użyć urządzenia low level API.

Zapewni to o wiele większą kontrolę, gdy coś pójdzie nie tak, jak to prawdopodobnie bywa z plikiem 11 GB.

Żądania do i od S3 zawodzą od czasu do czasu. Dzięki interfejsowi API niskiego poziomu możesz ponowić próbę przesłania części, jeśli się nie uda.

Refaktoryzacja przykład w docs Amazon nieco:

// Step 2: Upload parts. 
long filePosition = 0; 
for (int i = 1; filePosition < contentLength; i++) { 
    // Last part can be less than 5 MB. Adjust part size. 
    partSize = Math.min(partSize, (contentLength - filePosition)); 

    // Create request to upload a part. 
    UploadPartRequest uploadRequest = new UploadPartRequest() 
       .withBucketName(existingBucketName).withKey(keyName) 
       .withUploadId(initResponse.getUploadId()).withPartNumber(i) 
       .withFileOffset(filePosition) 
       .withFile(file) 
       .withPartSize(partSize); 

    // repeat the upload until it succeeds. 
    boolean anotherPass; 
     do { 
       anotherPass = false; // assume everythings ok 
       try { 
        // Upload part and add response to our list. 
        partETags.add(s3Client.uploadPart(uploadRequest).getPartETag()); 
       } catch (Exception e) { 
        anotherPass = true; // repeat 
       } 
     } while (anotherPass); 

    filePosition += partSize; 
} 

    // Step 3: complete. 
    CompleteMultipartUploadRequest compRequest = new 
        CompleteMultipartUploadRequest(
           existingBucketName, 
           keyName, 
           initResponse.getUploadId(), 
           partETags); 

    s3Client.completeMultipartUpload(compRequest); 

Uwaga: Nie jestem programistą Java więc mogłem namieszałem składniowo, ale mam nadzieję, że ten dostaje idziesz w dobrym kierunku. Ponadto, będziesz chciał dodać "licznik powtórzeń", aby zapobiec niekończącej się pętli, jeśli przesyłanie wielokrotnie się nie powiedzie.

+0

OK, czy możesz podać fragment kodu, jak ponowić część przesyłki po niepowodzeniu? – Alexey

+0

@Alexey - Dodałem próbkę, abyśmy mogli umieścić Cię na dobrej drodze. Podstawową ideą jest ponowienie próby części, jeśli nie powiedzie się, a nie tylko anulowanie całego przesyłania. –

+0

Dzięki, to rozwiązało mój problem. Dobrym pomysłem jest również użycie kilku wątków, aby umożliwić szybsze przesyłanie. – Alexey

2

Próbujesz przesłać pojedynczy plik o rozmiarze 11 GB? A może rozmiar wszystkich twoich plików to 11 GB? Ponieważ maksymalny limit rozmiaru pliku na S3 to 5 GB.

+0

Jeden plik o rozmiarze 11 GB. Obecnie nie ma limitu 5 GB, ponieważ jeśli prześlesz go za pomocą interfejsu internetowego Amazon (z opcją Włącz duże pliki), możesz przesłać pliki do 5 TB. Chcę po prostu zrobić to z programu Java – Alexey

+0

Cytat z ich Docs (link jest w moim poście powyżej): „Prześlij obiekty w częściach wykorzystujących wieloczęściowej wysyłania API można przesyłać duże obiekty, do 5 TB.” – Alexey

+0

Jest to nowa funkcja S3. –

1

Odpowiedź Geoffa Appleforda działa dla mnie. Chciałbym jednak dodać & & retryCount < MAX_RETRIES do instrukcji sterującej pętli while i przyrostu retryCount na każdym wyjątkiem złowionych wewnątrz chwilę.

Aviad

3

Na marginesie, 404 błędy mogą być wyrzucane, jeśli spróbujesz zrobić wieloczęściowy przesłać do klucza, który jest już pod wieloczęściowy przesłania.

1

Chciałem dodać komentarz Aby odpowiedzieć Geoff Appleford, ale tak nie pozwoli mi. Zasadniczo jego odpowiedź na używanie interfejsu API niskiego poziomu działa dobrze, ale nawet jeśli teraz mamy pętlę do-while, to sposób zaprojektowania pętli ma wbudowaną logikę ponowną. W jego fragmencie kodu pozycja pliku zwiększa się tylko wtedy, gdy jest sukces, w przeciwnym razie ponownie przesyłasz tę samą część.

Powiązane problemy