Elasticsearch节点故障怎么处理?
java.util.concurrent.TimeoutException: Connection lease request time out at org.apache.http.nio.pool.AbstractNIOConnPool.processPendingRequest(AbstractNIOConnPool.java:411) at org.apache.http.nio.pool.AbstractNIOConnPool.processNextPendingRequest(AbstractNIOConnPool.java:391) at org.apache.http.nio.pool.AbstractNIOConnPool.release(AbstractNIOConnPool.java:355) at org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager.releaseConnection(PoolingNHttpClientConnectionManager.java:391) at org.apache.http.impl.nio.client.AbstractClientExchangeHandler.releaseConnection(AbstractClientExchangeHandler.java:245) at org.apache.http.impl.nio.client.MainClientExec.responseCompleted(MainClientExec.java:387) at org.apache.http.impl.nio.client.DefaultClientExchangeHandlerImpl.responseCompleted(DefaultClientExchangeHandlerImpl.java:172) 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:81) at org.apache.http.impl.nio.client.InternalIODispatch.onInputReady(InternalIODispatch.java:39) at org.apache.http.impl.nio.reactor.AbstractIODispatch.inputReady(AbstractIODispatch.java:114) 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) 11:19:21.751 [I/O dispatcher 2] ERROR c.m.w.c.c.e.EsConfiguration - [onFailure,85] - 某个节点发生故障,故障地址是http://114.124.145.114:9200 11:19:21.751 [I/O dispatcher 2] ERROR c.m.w.c.c.e.EsOperationClient - [onFailure,69] - es异步插入失败=
插入的数据不能一下子大批量的执行,要分页!!!!!!!!!!!!!!!!!!!!!
分析
从提供的错误信息来看,java.util.concurrent.TimeoutException: Connection lease request time out
表示在尝试获取连接时超时了。这通常是由于以下几种原因之一:
- 网络问题:Elasticsearch 节点不可达或网络延迟高。
- 连接池配置问题:连接池的大小或超时时间设置不合理。
- Elasticsearch 节点负载过高:Elasticsearch 节点处理请求的速度较慢,导致连接池中的连接被占用时间过长。
- 客户端配置问题:客户端的超时时间设置过短。
解决方案
-
检查网络连接:
- 确保 Elasticsearch 节点
http://114.115.178.114:9200
可达。 - 使用
ping
或curl
命令测试网络连接:ping 114.115.178.114 curl -X GET "http://114.115.178.114:9200/_cluster/health?pretty"
- 确保 Elasticsearch 节点
-
调整连接池配置:
- 增加连接池的最大连接数。
- 增加连接超时时间。
-
优化 Elasticsearch 节点:
- 检查 Elasticsearch 节点的负载情况,确保其有足够的资源处理请求。
- 如果负载过高,可以考虑增加节点或优化索引和查询性能。
-
调整客户端配置:
- 增加客户端的超时时间。
修改代码
以下是修改后的代码,增加了连接池配置和客户端超时时间:
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.client.CredentialsProvider;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
public class ElasticsearchClientConfig {
public static RestHighLevelClient createClient() {
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials("username", "password"));
RestClientBuilder builder = RestClient.builder(
new HttpHost("114.115.178.114", 9200, "http"))
.setHttpClientConfigCallback(new HttpClientConfigCallback() {
@Override
public HttpAsyncClientBuilder customizeHttpClient(HttpAsyncClientBuilder httpClientBuilder) {
return httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)
.setMaxConnTotal(100) // 增加最大连接数
.setMaxConnPerRoute(20); // 增加每个路由的最大连接数
}
})
.setRequestConfigCallback(new RestClientBuilder.RequestConfigCallback() {
@Override
public org.apache.http.client.config.RequestConfig.Builder customizeRequestConfig(org.apache.http.client.config.RequestConfig.Builder requestConfigBuilder) {
return requestConfigBuilder
.setSocketTimeout(60000) // 增加套接字超时时间
.setConnectTimeout(60000) // 增加连接超时时间
.setConnectionRequestTimeout(60000); // 增加连接请求超时时间
}
});
return new RestHighLevelClient(builder);
}
public static void main(String[] args) {
RestHighLevelClient client = createClient();
// 使用 client 进行操作
// ...
try {
// 你的操作代码
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
关键点说明
-
连接池配置:
setMaxConnTotal(100)
:设置连接池的最大连接数为100。setMaxConnPerRoute(20)
:设置每个路由的最大连接数为20。
-
客户端超时时间:
setSocketTimeout(60000)
:设置套接字超时时间为60秒。setConnectTimeout(60000)
:设置连接超时时间为60秒。setConnectionRequestTimeout(60000)
:设置连接请求超时时间为60秒。
运行代码
运行上述代码,确保连接池配置和超时时间设置合理。如果问题仍然存在,可以通过日志输出和网络监控工具进一步排查问题。
其他建议
-
监控 Elasticsearch 节点:
- 使用 Kibana 或其他监控工具监控 Elasticsearch 节点的健康状况和性能指标。
- 检查日志文件,查看是否有其他错误或警告信息。
-
优化查询:
- 确保查询条件和索引设计合理,避免全表扫描。
- 使用合理的分页参数,避免一次性返回大量数据。
设置下集群配置类的超时时间和查询ES的分页大小
/**
* es集群配置类
* @author sunpeiyang
* @date 2024/11/7 17:22
*/
@Slf4j
@Configuration
public class EsConfiguration {
private static final int ADDRESS_LENGTH = 2;
private static final String HTTP_SCHEME = "http";
@Value("${es.hosts:114.23.45.22:9200}")
private String[] hosts;
@Value("${es.username:elastic}")
private String username;
@Value("${es.password:elastic}")
private String password;
@Value("${es.connectTimeout:60000}")
private Integer connectTimeout;
@Value("${es.socketTimeout:60000}")
private Integer socketTimeout;
@Value("${es.connectionRequestTimeout:60000}")
private Integer connectionRequestTimeout;
public CredentialsProvider basicCredentialsProvider() {
if (StringUtils.isNotBlank(username) && StringUtils.isNotBlank(password)) {
CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
credentialsProvider.setCredentials(AuthScope.ANY,
new UsernamePasswordCredentials(username, password));
return credentialsProvider;
}
return null;
}
@Bean
public RestClientBuilder restClientBuilder() {
HttpHost[] httpHosts = Arrays.stream(hosts)
.map(this::getHttpHost)
.filter(Objects::nonNull)
.toArray(HttpHost[]::new);
RestClientBuilder builder = RestClient.builder(httpHosts);
CredentialsProvider credentialsProvider = basicCredentialsProvider();
if (credentialsProvider != null) {
builder.setHttpClientConfigCallback(httpAsyncClientBuilder -> httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider));
builder.setRequestConfigCallback(requestConfigBuilder -> {
//设置连接超时时间
requestConfigBuilder.setConnectTimeout(connectTimeout);
//设置socket超时时间s
requestConfigBuilder.setSocketTimeout(socketTimeout);
//设置连接请求超时时间
requestConfigBuilder.setConnectionRequestTimeout(connectionRequestTimeout);
return requestConfigBuilder;
});
builder.setFailureListener(new RestClient.FailureListener() {
/*3.设置每次节点发生故障时收到通知的侦听器。内部嗅探到故障时被启用。*/
@Override
public void onFailure(Node node) {
log.error("某个节点发生故障,故障地址是" + node.getHost());
}
});
}
return builder;
}
@Bean(name = "highLevelClient")
public RestHighLevelClient highLevelClient(@Autowired RestClientBuilder restClientBuilder) {
return new RestHighLevelClient(restClientBuilder);
}
private HttpHost getHttpHost(String host) {
assert StringUtils.isNotEmpty(host);
String[] address = host.split(":");
if (address.length == ADDRESS_LENGTH) {
String ip = address[0];
int port = Integer.parseInt(address[1]);
return new HttpHost(ip, port, HTTP_SCHEME);
} else {
return null;
}
}
}
使用Elasticsearch需要注意什么?
使用 Elasticsearch 时,除了理解其基本功能和配置外,还需要关注一些关键的最佳实践和性能优化措施。以下是使用 Elasticsearch 时需要注意的几个重要方面:
1. 硬件和资源配置
Elasticsearch 是一个内存密集型的应用,合理的硬件资源配置对于性能至关重要。
内存:Elasticsearch 强烈依赖于 JVM 堆内存(Heap Memory)。推荐设置堆内存为物理内存的 50%,但不超过 30GB。超过 30GB 时,JVM 使用指针压缩会失效,导致性能下降。
磁盘:为了获得较高的 I/O 性能,最好将数据存储在 SSD 上,避免使用传统机械硬盘。
CPU:Elasticsearch 的性能受 CPU 性能影响较大,特别是在处理大规模查询时,选择多核 CPU 会提升性能。
2. 集群和节点配置
Elasticsearch 通常部署在多个节点上,以提高数据的冗余性、可用性和查询性能。
主节点 (Master Node):主节点负责集群管理和元数据管理,推荐将主节点与数据节点分开,避免主节点过载。
数据节点 (Data Node):数据节点存储和处理数据。你可以根据需求选择多个数据节点,以分担负载。
客户端节点 (Coordinating Node):客户端节点主要用于路由查询请求到相应的数据节点。通常情况下,你可以直接通过负载均衡的方式访问客户端节点。
合理配置分片和副本:
分片(Shards):数据在 Elasticsearch 中以分片的方式存储,默认情况下每个索引有 5 个主分片。合理的分片数量可以提高查询性能和数据处理效率。过多的分片会带来管理和性能问题,过少的分片会导致数据分布不均,影响性能。
副本(Replicas):副本提供数据的冗余备份,并且可以提高查询的并发性。建议根据需求调整副本数量。副本数越多,查询性能越高,但也会占用更多的存储空间。
3. 索引设计与映射
索引设计不当会影响查询性能和存储效率,因此在设计索引时需要特别注意:
映射(Mapping):映射定义了索引中文档字段的类型(如 text、keyword、date 等),合理的映射可以优化存储和查询性能。避免动态映射生成不必要的字段。
字段类型选择:选择合适的字段类型。例如,text 类型适用于需要分词的字段,keyword 类型适用于精确匹配的字段,date 类型适用于时间相关字段。
避免过多的字段:尽量避免不必要的字段,避免大量使用 nested 类型和 object 类型,因为它们会增加查询复杂度。
文档大小:避免单个文档过大,否则会影响性能。将大文档拆分成多个小文档会更有利于性能。
4. 查询性能优化
Elasticsearch 的查询性能直接影响到系统的响应速度和稳定性,以下是一些常见的优化建议:
使用过滤器(Filters)而非查询(Queries):过滤器不会影响评分,因此它们比查询更高效。对于常用的精确匹配条件,使用 filter 代替 query。
避免使用通配符(Wildcard)查询:通配符查询(如 * 和 ?)会非常消耗性能。尽量避免或只在需要时使用。
合理使用分页:避免对大量数据进行深度分页查询。深度分页会导致性能问题,因为 Elasticsearch 需要加载大量无用的结果。可以使用 search_after 或 scroll API 来替代。
避免过于复杂的查询:复杂的查询(如嵌套查询、多层聚合)会消耗更多的计算资源。根据业务需求合理简化查询。
5. 监控与日志管理
集群健康监控:定期检查集群健康状态,使用如 /_cluster/health API 查看集群的健康状况。
日志管理:定期检查 Elasticsearch 日志,查看是否有性能瓶颈或错误信息。日志可以帮助你快速发现潜在问题。
使用监控工具:可以使用 Elastic Stack(如 Kibana)监控集群性能,查看节点的资源使用情况和查询执行时间。
6. 数据备份和恢复
快照(Snapshot):定期进行数据快照备份。Elasticsearch 提供了 snapshot 和 restore API 来进行集群的数据备份和恢复。确保配置好快照存储位置(如远程仓库),以防数据丢失。
恢复策略:在恢复时,根据恢复的需求和节点状态合理选择恢复策略,避免造成集群的负载过高。
7. 安全性
Elasticsearch 默认并未启用认证和授权,因此,使用时需要考虑安全性:
启用认证:使用 Elastic Stack 的 X-Pack 或者第三方插件启用身份验证,限制对 Elasticsearch 的访问。
网络安全:通过防火墙、IP 白名单等手段限制访问,确保只有授权的主机或用户能访问 Elasticsearch。
加密通信:启用 TLS/SSL 加密,确保客户端和 Elasticsearch 之间的通信安全。
8. 分布式特性和容错
数据冗余:通过副本(replica)配置实现数据冗余,确保节点故障时数据不丢失。
分布式处理:理解 Elasticsearch 的分布式特性,如何在多个节点间分配分片、处理请求。合理配置节点间的负载均衡,提高系统的容错能力。
9. 升级和兼容性
版本兼容性:升级 Elasticsearch 时,需要注意版本之间的兼容性。新版本可能引入不兼容的变更,因此升级前需进行充分的测试。
升级策略:尽量避免直接在生产环境中进行大规模版本升级。可以先在开发环境中验证新版本的性能和功能,再推送到生产环境。
总结:
使用 Elasticsearch 时,合理的资源配置、索引设计、查询优化、安全管理以及监控维护是确保系统高效、稳定和安全的关键。遵循上述最佳实践,定期进行性能优化和监控,有助于提升 Elasticsearch 集群的可用性和响应速度。
原文地址:https://blog.csdn.net/weixin_44372802/article/details/143619190
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!