2015-11-28 17 views
6

Ich muss große Dateien (mindestens 14MB) von der Cosmos-Instanz des FIWARE Labs zu meinem Backend übertragen.Wie kann ich Teile von Dateien mit Hadoop WebHDFS lesen und übertragen?

verwenden ich die Feder RestTemplate als Client-Schnittstelle für die Hadoop WebHDFS REST API beschrieben here aber ich laufe in eine IO Ausnahme:

Exception in thread "main" org.springframework.web.client.ResourceAccessException: I/O error on GET request for "http://cosmos.lab.fiware.org:14000/webhdfs/v1/user/<user.name>/<path>?op=open&user.name=<user.name>":Truncated chunk (expected size: 14744230; actual size: 11285103); nested exception is org.apache.http.TruncatedChunkException: Truncated chunk (expected size: 14744230; actual size: 11285103) 
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:580) 
    at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:545) 
    at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:466) 

Dies ist der eigentliche Code, der die Ausnahme erzeugt:

RestTemplate restTemplate = new RestTemplate(); 
restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory()); 
restTemplate.getMessageConverters().add(new ByteArrayHttpMessageConverter()); 
HttpEntity<?> entity = new HttpEntity<>(headers); 

UriComponentsBuilder builder = 
    UriComponentsBuilder.fromHttpUrl(hdfs_path) 
     .queryParam("op", "OPEN") 
     .queryParam("user.name", user_name); 

ResponseEntity<byte[]> response = 
    restTemplate 
     .exchange(builder.build().encode().toUri(), HttpMethod.GET, entity, byte[].class); 

FileOutputStream output = new FileOutputStream(new File(local_path)); 
IOUtils.write(response.getBody(), output); 
output.close(); 

Ich denke, das liegt an einem Übertragungs-Timeout auf der Cosmos-Instanz, so versuchte ich senden Sie eine curl auf dem Pfad durch Angabe offset, buffer and length Parameter, aber sie scheinen zu sein ignoriert: Ich habe die ganze Datei bekommen.

Vielen Dank im Voraus.

+0

Vielleicht werfen Sie einen Blick auf py webhdfs gibt Ihnen einige Hinweise -> https://github.com/pywebhdfs/pywebhdfs/blob/master/pywebhdfs/webhdfs.py#L48 – ravwojdyla

+1

Danke, aber es hilft nicht. Das Problem ist, dass der optionale length-Parameter der OPEN-Operation (siehe 'def read_file (self, path, ** kwargs) 'in Ihrem Link) vom Server vollständig ignoriert wird –

Antwort

4

Ok, ich habe eine Lösung gefunden. Ich verstehe nicht warum, aber die Übertragung ist erfolgreich, wenn ich einen Jetty HttpClient anstelle von RestTemplate (und damit Apache HttpClient) verwende. Dies funktioniert jetzt:

Gibt es einen bekannten Fehler auf dem Apache Http Client für chunked Dateien übertragen?

Wurde in meiner RestTemplate-Anfrage etwas falsch gemacht?

UPDATE: Ich habe nicht noch eine Lösung

Nach einigen Tests, die ich sehen, dass ich Probleme meine gelöst haben nicht. Ich fand heraus, dass die Hadoop-Version auf der Cosmos-Instanz installiert ist ziemlich alt Hadoop 0,20.2-cdh3u6 und ich habe gelesen, dass WebHDFS partielle Dateiübertragung mit length Parameter (introduced since v 0.23.3) nicht unterstützt. Dies sind die Header ich vom Server empfangen werden, wenn ich eine GET-Anfrage curl mit senden:

Access-Control-Allow-Origin: * 
Access-Control-Allow-Methods: HEAD, POST, GET, OPTIONS, DELETE 
Access-Control-Allow-Headers: origin, content-type, X-Auth-Token, Tenant-ID, Authorization 
server: Apache-Coyote/1.1 
set-cookie: hadoop.auth="u=<user>&p=<user>&t=simple&e=1448999699735&s=rhxMPyR1teP/bIJLfjOLWvW2pIQ="; Version=1; Path=/ 
Content-Type: application/octet-stream; charset=utf-8 
content-length: 172934567 
date: Tue, 01 Dec 2015 09:54:59 GMT 
connection: close 

Wie Sie die Connection-Kopfzeile sehen gesetzt zu schließen. Tatsächlich wird die Verbindung normalerweise jedes Mal geschlossen, wenn die GET-Anforderung länger als 120 Sekunden dauert, selbst wenn die Dateiübertragung nicht abgeschlossen wurde.

Zusammenfassend kann ich sagen, dass Cosmos völlig nutzlos ist, wenn es keine große Dateiübertragung unterstützt.

Bitte korrigieren Sie mich, wenn ich falsch liege, oder wenn Sie einen Workaround kennen.