ES 数据插入异常原因分析

24-01-23.15:50:18.635 [I/O dispatcher 1] WARN  org.elasticsearch.client.RestClient  - request [HEAD http://localhost:9200/alarm_msg?ignore_throttled=false&include_type_name=true&ignore_unavailable=false&expand_wildcards=open&allow_no_indices=true] returned 1 warnings: [299 Elasticsearch-7.17.13-2b211dbb8bfdecaf7f5b44d356bdfe54b1050c13 "[ignore_throttled] parameter is deprecated because frozen indices have been deprecated. Consider cold or frozen tiers in place of frozen indices."]
Exception in thread "I/O dispatcher 1" java.lang.AssertionError
    at org.elasticsearch.client.Response.assertWarningValue(Response.java:193)
    at org.elasticsearch.client.Response.extractWarningValueFromWarningHeader(Response.java:183)
    at org.elasticsearch.client.Response.getWarnings(Response.java:205)
    at org.elasticsearch.client.RestClient$1.completed(RestClient.java:546)
    at org.elasticsearch.client.RestClient$1.completed(RestClient.java:537)

        Springboot 执行 ES 单元测试时发生上述异常 , 看提示应该是因为使用了 ignore_throttled 过期参数导致的,但是我的查询并没有使用这个字段,那它是从哪里来的呢?

先 debug 查看异常处代码 Response.assertWarningValue

private static final Pattern WARNING_HEADER_PATTERN = Pattern.compile(
            "299 " + // warn code
            "Elasticsearch-\\d+\\.\\d+\\.\\d+(?:-(?:alpha|beta|rc)\\d+)?(?:-SNAPSHOT)?-(?:[a-f0-9]{7}|Unknown) " + // warn agent
            "\"((?:\t| |!|[\\x23-\\x5B]|[\\x5D-\\x7E]|[\\x80-\\xFF]|\\\\|\\\\\")*)\"( " + // quoted warning value, captured
            // quoted RFC 1123 date format
            "\"" + // opening quote
            "(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun), " + // weekday
            "\\d{2} " + // 2-digit day
            "(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) " + // month
            "\\d{4} " + // 4-digit year
            "\\d{2}:\\d{2}:\\d{2} " + // (two-digit hour):(two-digit minute):(two-digit second)
            "GMT" + // GMT
            "\")?");

private static boolean assertWarningValue(final String s, final String warningValue) {
        final Matcher matcher = WARNING_HEADER_PATTERN.matcher(s);
        final boolean matches = matcher.matches();
        assert matches;
        return matcher.group(1).equals(warningValue);
}

这段代码是从 es 请求的响应中提取告警信息,判断是否符合断言,该正则表达式分为三部分

1、299 Elasticsearch-xxx...

2、捕获的告警信息

3、时间(可有可无)

对比运行时异常信息发现,299 Elasticsearch-7.17.13-2b211dbb8bfdecaf7f5b44d356bdfe54b1050c13 不在 WARNING_HEADER_PATTERN 约束的版本内,导致匹配失败,分析下我使用的版本信息 

  • maven 依赖信息
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>2.2.6.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-elasticsearch</artifactId>
        <version>3.2.6.RELEASE</version>
    </dependency>
  • ES  版本 7.17.13

查看官网各版本对应关系:
 Spring Data Elasticsearch - Reference Documentation

升级 springboot 版本为 2.7.10

再次执行单元测试通过,没有异常信息,数据正常插入ES

注:[ignore_throttled] parameter is deprecated because frozen indices have been deprecated. Consider cold or frozen tiers in place of frozen indices. 是什么 ?

 什么是 ignore_throttled ?

  • ignore_throttled=true 会忽略被限制的分片并继续执行搜索操作,可能导致搜索结果的不完整性(分片受到资源限制或负载高,且无法及时响应搜索请求,这些被限制的分片将会被忽略);而 ignore_throttled=false 会等待被限制的分片完成操作并返回完整的结果,确保搜索结果的完整性和准确性,但可能会增加搜索请求的响应时间。
  •  ignore_throttled 参数在版本6.4.0中开始被废弃(deprecated),并且在版本7.0.0中完全移除(removed),建议使用默认值false
  • 在 7.0 版本中,可以使用 search.allow_partial_results(true/false 用于控制搜索操作是否允许返回部分结果) 替代 ignore_throttled 参数 ignore_throttled

 为什么在高版本中不需要ignore_throttled了?

  • 改进索引策略:高版本的Elasticsearch引入了改进的索引策略,其中包括更好的分片管理和负载均衡机制。这些改进使得Elasticsearch能够更好地处理高负载和资源限制的情况,而不需要显式地忽略被限制的分片。
  • 自适应限速(Adaptive Throttling):较高版本的Elasticsearch引入了自适应限速机制,它根据系统的负载情况自动调整操作的速度。自适应限速能够更智能地应对资源限制和负载情况,而无需开发人员手动设置忽略被限制的分片。
  • 保证结果的完整性:忽略被限制的分片可能会导致搜索结果的不完整性,因为被限制的分片可能包含一部分数据。为了确保搜索结果的准确性和完整性,建议不忽略被限制的分片,而是等待它们完成操作并返回完整的结果。
  • 19
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Elasticsearch 6.5.4 中,可以使用 Java API 批量插入数据。下面是一个示例代码: ```java import org.elasticsearch.action.bulk.BulkRequest; import org.elasticsearch.action.bulk.BulkResponse; import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.rest.RestStatus; import java.io.IOException; import java.util.List; public class ElasticsearchBulkInsert { private static final String INDEX_NAME = "my_index"; private static final String TYPE_NAME = "_doc"; public static void bulkInsert(RestHighLevelClient client, List<String> documents) throws IOException { BulkRequest bulkRequest = new BulkRequest(); for (String document : documents) { IndexRequest indexRequest = new IndexRequest(INDEX_NAME, TYPE_NAME); indexRequest.source(document, XContentType.JSON); bulkRequest.add(indexRequest); } try { BulkResponse bulkResponse = client.bulk(bulkRequest, RequestOptions.DEFAULT); if (bulkResponse.hasFailures()) { // 处理错误 for (BulkItemResponse bulkItemResponse : bulkResponse) { if (bulkItemResponse.isFailed()) { BulkItemResponse.Failure failure = bulkItemResponse.getFailure(); String id = bulkItemResponse.getId(); String message = failure.getMessage(); RestStatus status = failure.getStatus(); // 处理错误 } } } } catch (IndexNotFoundException e) { // 处理索引不存在异常 } } } ``` 在上面的代码中,我们首先创建了一个 `BulkRequest` 对象,然后循环要插入的文档,将每个文档构造成一个 `IndexRequest` 对象,并调用 `bulkRequest.add()` 方法将其添加到 `BulkRequest` 中。最后,调用 `client.bulk()` 方法执行批量插入操作。 要注意的是,如果批量插入过程中出现错误,可以通过检查 `BulkResponse` 对象中的 `hasFailures()` 方法来判断是否存在错误。如果存在错误,可以通过遍历 `BulkItemResponse` 对象来处理每个文档的错误信息。如果在批量插入时发现索引不存在,可以捕获 `IndexNotFoundException` 异常并进行处理。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值