gpt4 book ai didi

hadoop - 如何使用 Hadoop WebHDFS 读取和传输文件 block ?

转载 作者:可可西里 更新时间:2023-11-01 14:16:59 27 4
gpt4 key购买 nike

我需要将大文件(至少 14MB)从 FIWARE 实验室的 Cosmos 实例传输到我的后端。

我使用 Spring RestTemplate 作为 Hadoop WebHDFS REST API 的客户端接口(interface) here但是我遇到了 IO 异常:

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)

这是生成异常的实际代码:

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();

我认为这是由于 Cosmos 实例上的传输超时,所以我尝试通过指定 offset、buffer 和 length 参数在路径上发送 curl,但它们似乎被忽略了:我得到了整个文件。

提前致谢。

最佳答案

好的,我找到了解决方案。我不明白为什么,但是如果我使用 Jetty HttpClient 而不是 RestTemplate(以及 Apache HttpClient),传输就会成功。这现在有效:

ContentExchange exchange = new ContentExchange(true){
ByteArrayOutputStream bos = new ByteArrayOutputStream();

protected void onResponseContent(Buffer content) throws IOException {
bos.write(content.asArray(), 0, content.length());
}

protected void onResponseComplete() throws IOException {
if (getResponseStatus()== HttpStatus.OK_200) {
FileOutputStream output = new FileOutputStream(new File(<local_path>));
IOUtils.write(bos.toByteArray(), output);
output.close();
}
}

};

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

exchange.setURL(builder.build().encode().toUriString());
exchange.setMethod("GET");
exchange.setRequestHeader("X-Auth-Token", <token>);

HttpClient client = new HttpClient();
client.setConnectorType(HttpClient.CONNECTOR_SELECT_CHANNEL);
client.setMaxConnectionsPerAddress(200);
client.setThreadPool(new QueuedThreadPool(250));
client.start();
client.send(exchange);
exchange.waitForDone();

在 Apache Http Client 上是否存在用于分块文件传输的已知错误?

我在 RestTemplate 请求中做错了什么吗?

更新:我仍然没有解决方案

经过几次测试后,我发现我没有解决我的问题。我发现 Cosmos 实例上安装的 hadoop 版本很旧 Hadoop 0.20.2-cdh3u6 并且我读到 WebHDFS 不支持使用 length 参数的部分文件传输( introduced since v 0.23.3 )。这些是我使用 curl 发送 GET 请求时从服务器收到的 header :

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

如您所见,Connection header 设置为关闭。实际上,每次 GET 请求持续超过 120 秒时,连接通常会关闭,即使文件传输尚未完成也是如此。

总而言之,如果 Cosmos 不支持大文件传输,我可以说它完全没有用。

如果我错了,或者您知道解决方法,请纠正我。

关于hadoop - 如何使用 Hadoop WebHDFS 读取和传输文件 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33974754/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com