Elasticsearch 响应数据压缩功能详解

本文详述了Elasticsearch如何启用HTTP/TCP压缩以优化大数据传输,减少网络延迟。从7.8版本开始,Java库对压缩支持更加友好,高级客户端自动解压,低级客户端需手动处理。7.7及以下版本,高级客户端不支持压缩数据的处理,而低级客户端则需要自定义解压逻辑。7.9及更高版本,低级客户端也提供了内置解压功能。开发者应根据版本调整相应代码来处理压缩响应。
摘要由CSDN通过智能技术生成

压缩非常奇妙,可以将数据压缩比原始大小更小。我们知道WinRaR,7Zip等压缩工具。Elasticsearch也提供压缩数据功能,可实现对在客户端和服务端节点之间传输数据的压缩。压缩对于处理大数据传输时可减少网络延迟,本文主要内容包括:启用HTTP/TCP压缩,处理Elasticsearch不同版本的压缩的响应信息。

启用HTTP/TCP压缩

ES使得修改HTTP压缩非常容易,仅仅在 elasticsearch.yml文件中提供下面属性即可:

http.compression: true
http.compression_level: 1

TCP压缩使用下面属性:

transport.compress: true

处理Elasticsearch不同版本的压缩的响应信息

前节启用了压缩,下面讨论如何处理压缩响应信息。对于TCP压缩无需任何处理,Elasticsearch使用tcp协议在不同节点之间通信能够正确解压。但启用http压缩,客户端(终端、postman、java client)需要知道如何解压缩,否则会收到无法阅读数据。下面主要聚焦java client情况。

2020.06.18 Elasticsearch7.8版本发布,其中Java库处理压缩非常容易。可以参考文档:Elasticsearch 7.8 release notes

虽然你启用了数据压缩,只有客户端请求压缩时Elasticsearch才压缩数据。java 客户端通过Http request发送额外请求选项要求压缩。请看示例:

RequestOptions.Builder requestOptions = RequestOptions.DEFAULT.toBuilder()
    .addHeader("Accept-Encoding", "gzip")
    .addHeader("Content-type", "application/json");

Elasticsearch 7.7 及以下版本处理压缩响应

ES的java库提供两种客户端,高级Rest客户端和低级Rest客户端。高级不支持处理压缩数据,当接收到压缩响应会直接跑车运行时异常。低级客户端提供Elasticsearch原始响应,因此可以进行解压。有多种方式实现解压,这里仅设计两种:

RequestOptions.Builder requestOptions = RequestOptions.DEFAULT.toBuilder()
    .addHeader("Accept-Encoding", "gzip")
    .addHeader("Content-type", "application/json");

Request request = new Request("GET", "test/_search");
request.setOptions(requestOptions);
Response response = client.getLowLevelClient().performRequest(request);
byte[] entity = EntityUtils.toByteArray(response.getEntity())
String decompressedResponse = "";

try (ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(entity);
     GZIPInputStream gzipInputStream = new GZIPInputStream(byteArrayInputStream);
     BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(gzipInputStream, StandardCharsets.UTF_8));) {
    decompressedResponse = bufferedReader.lines()
                    .collect(Collectors.joining());
}

System.out.println(decompressedResponse)

也可以通过下面代码进行解压:

RequestOptions.Builder requestOptions = RequestOptions.DEFAULT.toBuilder()
    .addHeader("Accept-Encoding", "gzip")
    .addHeader("Content-type", "application/json");

Request request = new Request("GET", "test/_search");
request.setOptions(requestOptions);
Response response = client.getLowLevelClient().performRequest(request);
String decompressedResponse = EntityUtils.toString(new GzipDecompressingEntity(response.getEntity()))

System.out.println(decompressedResponse)

Elasticsearch 7.8处理压缩响应

rest高级客户端自动解压数据。上面示例可重写为:

RequestOptions.Builder requestOptions = RequestOptions.DEFAULT.toBuilder()
    .addHeader("Accept-Encoding", "gzip")
    .addHeader("Content-type", "application/json");

SearchRequest request = new SearchRequest("twitter");
SearchResponse searchResponse = client.search(searchRequest, requestOptions);

System.out.println(decompressedResponse)

作为开发者无需写额外逻辑处理响应。如果使用低级Rest客户端仍然需要自己解压缩逻辑,与上面示例一致。

Elasticsearch Release 7.9 及未来 8.0版本

随着新版功能升级,低级Rest客户端也提供了内置解压功能,可以查看pull/55413。这将大大提升java库的开发者应用体验。示例代码如下:

RequestOptions.Builder requestOptions = RequestOptions.DEFAULT.toBuilder()
    .addHeader("Accept-Encoding", "gzip")
    .addHeader("Content-type", "application/json");

Request request = new Request("GET", "test/_search");
request.setOptions(requestOptions);

Response response = client.getLowLevelClient().performRequest(request);
String responseBody = EntityUtils.toString(response.getEntity());

System.out.println(responseBody);

低级Rest客户端的变化开发者需要留意。如果你已经在代码中增加了解压逻辑会抛出异常,因为尝试解压未压缩的数据。高级客户端没有变化,仍默认提供的解压功能。

总结

本文介绍了Elasticsearch响应数据压缩与解压缩功能,并给出不同版本的实现差异及示例代码。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值