Elasticsearch 常见报错及处理方式

1.更新操作版本冲突异常,乐观锁异常,报409

org.elasticsearch.client.ResponseException: method [POST], host [https://xxx.xx.xx.xx:9200], URI [/docs/_update/3269-60], status line [HTTP/1.1 409 Conflict]
{"error":{"root_cause":[{"type":"version_conflict_engine_exception","reason":"[3269-60]: version conflict, required seqNo [1411133], primary term [1]. current document has seqNo [1411134] and primary term [1]","index_uuid":"lgIyKKxKSYy5HpNnGNz6sg","shard":"0","index":"doc_index"}],"type":"version_conflict_engine_exception","reason":"[3269-60]: version conflict, required seqNo [1411133], primary term [1]. current document has seqNo [1411134] and primary term [1]","index_uuid":"lgIyKKxKSYy5HpNnGNz6sg","shard":"0","index":"doc_index"},"status":409}
	at org.elasticsearch.client.RestClient.convertResponse(RestClient.java:347)
	at org.elasticsearch.client.RestClient.access$1900(RestClient.java:108)
	at org.elasticsearch.client.RestClient$1.completed(RestClient.java:397)
	at org.elasticsearch.client.RestClient$1.completed(RestClient.java:393)
	at org.apache.http.concurrent.BasicFuture.completed(BasicFuture.java:119)
	at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.responseCompleted(DefaultClientExchangeHandlerImpl.java:182)
	at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.processResponse(HttpAsyncRequestExecutor.java:448)
	at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.inputReady(HttpAsyncRequestExecutor.java:338)
	at org.apache.http.impl.nio.DefaultNHttpClientConnection.consumeInput(DefaultNHttpClientConnection.java:265)
	at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:87)
	at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:40)
	at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:121)
	at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:162)
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:337)
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:276)
	at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
	at java.lang.Thread.run(Thread.java:745)

这个错误主要是在频繁更新文档时出现,原因是ES在更新文档时用乐观锁来保证更新操作的一致性,它会维护一个序列号,当一个线程执行更新操作前取得序列号后如果如果其他线程完成更新操作就会导致序列号增长,这时前一个线程执行更新操作时序列号小于当前序列号,从而引发乐观锁异常。

该问题的解决方式很简单。ES提供了失败重试参数,对于并发量不是特别高的应用,设置失败重试参数基本上就可以避免这类错误了。

elasticsearchAsyncClient.update(e -> e
                                .index(indexAlias)
                                .id(doc.getId())
                                .doc(doc)
                                .detectNoop(false)
                                .retryOnConflict(3), //失败后重试3次
                        ProcDocEsV.class)
                .whenComplete((response, exception) -> {
                    // ....
                });

2.连接超时异常

java.net.SocketTimeoutException: 30,000 milliseconds timeout on connection http-outgoing-15 [ACTIVE]
	at org.apache.http.nio.protocol.HttpAsyncRequestExecutor.timeout(HttpAsyncRequestExecutor.java:387)
	at org.apache.http.impl.nio.client.InternalIODispatch.onTimeout(InternalIODispatch.java:98)
	at org.apache.http.impl.nio.client.InternalIODispatch.onTimeout(InternalIODispatch.java:40)
	at org.apache.http.impl.nio.reactor.AbstractIODispatch.timeout(AbstractIODispatch.java:175)
	at org.apache.http.impl.nio.reactor.BaseIOReactor.sessionTimedOut(BaseIOReactor.java:261)
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.timeoutCheck(AbstractIOReactor.java:502)
	at org.apache.http.impl.nio.reactor.BaseIOReactor.validate(BaseIOReactor.java:211)
	at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:280)
	at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)
	at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:591)
	at java.lang.Thread.run(Thread.java:745)

这个问题可能的原因有两种:

(1)单次请求数据太多,设置的请求超时时间太小。ES默认的socketTimeout 和 connectTimeout 参数分别为30秒和1秒,可以根据需要调整参数,可以在配置ES连接的时候设置此参数。

RestClient restClient=RestClient
                .builder(new HttpHost(host, Integer.parseInt(port), "https"))
                .setRequestConfigCallback(
                        requestConfigBuilder -> requestConfigBuilder
                                .setConnectTimeout(5000)
                                .setSocketTimeout(60000))
                .build();

(2)ES服务长时间没有收到请求时,会关闭应用之间建立的连接,这时发起请求并不会先判断连接是否可达。需要设置保活策略,保证连接不被断开。

  RestClient restClient=RestClient
                .builder(new HttpHost(host, Integer.parseInt(port), "https"))
                .setHttpClientConfigCallback(hc -> hc
                        .setSSLContext(sslContext)
                        .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                        .setKeepAliveStrategy((response, context) -> Duration.ofMinutes(5).toMillis()))
                .build();

参考博文:

Elasticsearch High Level Rest Client偶现访问集群超时的问题定位与解决-腾讯云开发者社区-腾讯云 (tencent.com)

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值