【ES】Elasticsearch常见问题与解决

发布时间:2023年12月28日

目录

1. 集群健康问题

2. 性能问题

3. 映射问题

4. 分片问题

5. 内存问题

6. 硬件问题

7. 配置问题

8. 安全问题

9. 网络问题

10. 版本不兼容


????????Elasticsearch (ES) 是一个强大的开源搜索和分析引擎,广泛用于全文搜索、日志和数据分析等场景。由于其复杂性,用户可能会遇到各种问题。以下是一些常见的 Elasticsearch 问题以及相应的解决方法:

Elasticsearch常见问题

1. 集群健康问题

问题: ES 集群健康状态不是绿色(可能是黄色或红色)。

解决方法:
- 黄色: 通常意味着至少一个副本分片没有被正确分配。检查是否有足够的节点来承载副本分片。
- 红色: 表示至少一个主分片未被分配。检查节点日志,确定是否有硬件故障或网络问题。
- 使用 `GET /_cluster/health` 查看集群健康状态,并根据输出解决具体问题。

场景举例:

有次控制台报这个

org.elasticsearch.action.search.SearchPhaseExecutionException: all shards failed
Caused by: org.elasticsearch.index.query.QueryShardException: No mapping found for [order] in order to sort on

org.lasticsearch.action.search.SearchPhaseExecutionException:所有碎片都失败
由:org.lasticsearch/index.query.QueryShardException引起:找不到[order]的映射以便排序

查看管理台RED

然后分片改成3个,重建索引,重新发布,还是不行,

最后发现是索引没写进去数据,很简单,也很尴尬..

模拟代码

ClusterHealthResponse healthResponse = client.cluster().health(new ClusterHealthRequest(), RequestOptions.DEFAULT);
String clusterName = healthResponse.getClusterName();
ClusterHealthStatus status = healthResponse.getStatus();

2. 性能问题

问题: 查询慢,索引速度慢。

解决方法:
- 查询优化: 确保使用正确的查询类型,避免使用高成本操作如深度分页(deep pagination)。
- 索引优化: 使用批量(bulk)API进行索引操作,调整刷新频率和分片数量。
- 硬件检查: 检查是否硬件(如 CPU、内存、磁盘IO)成为瓶颈。

// 检索慢查询日志
GetSettingsRequest request = new GetSettingsRequest().indices("your_index").includeDefaults(true);
GetSettingsResponse response = client.indices().getSettings(request, RequestOptions.DEFAULT);
String slowLogThreshold = response.getSetting("your_index", "index.search.slowlog.threshold.query.warn");

3. 映射问题

问题: 映射错误导致无法索引数据。

解决方法:
- 映射定义: 在索引数据前定义好映射,确保数据类型与映射匹配。
- 动态映射: 如果不希望自动创建映射,可以在索引设置中禁用动态映射。
- 重建索引: 如果映射错误,可能需要创建新索引并重新导入数据。

// 获取映射
GetMappingsRequest request = new GetMappingsRequest().indices("your_index");
GetMappingsResponse getMappingResponse = client.indices().getMapping(request, RequestOptions.DEFAULT);
Map<String, MappingMetadata> allMappings = getMappingResponse.mappings();

4. 分片问题

问题: 分片数量不当。

解决方法:
- 分片数量调整: 分片数量过多会增加集群负担,过少则可能不利于性能。根据数据量调整分片大小。
- 使用分片分配: 调整 `index.number_of_shards` 和 `index.number_of_replicas` 配置来更改分片数量和副本数量。

// 调整分片
ResizeRequest request = new ResizeRequest("target_index", "source_index");
request.getTargetIndexRequest().settings(Settings.builder()
    .put("index.number_of_shards", "new_number_of_shards")
    .put("index.number_of_replicas", "new_number_of_replicas"));
client.indices().resize(request, RequestOptions.DEFAULT);

5. 内存问题

问题: JVM 堆内存不足。

解决方法:
- 堆大小调整: 增加 JVM 堆大小,但不要超过物理内存的 50% 或 32GB(由于压缩指针的限制)。
- 内存压力分析: 使用 ES 的节点状态API分析内存压力,并相应调整。

// 检查节点状态,包括内存使用情况
NodesStatsRequest request = new NodesStatsRequest();
NodesStatsResponse response = client.nodes().stats(request, RequestOptions.DEFAULT);
JvmStats jvmStats = response.getNodesMap().get("nodeId").getJvm();

6. 硬件问题

问题: 硬件资源不足导致性能瓶颈。

解决方法:
- 资源升级: 根据需求升级 CPU、内存或磁盘。
- 负载均衡: 确保集群中的负载均衡,避免个别节点过载。

7. 配置问题

问题: 不当的配置导致问题。

解决方法:
- 配置审查: 定期审查配置文件,确保所有配置项都是必要和优化的。
- 文档参考: 参考官方文档进行配置。

// 获取当前的索引设置
GetSettingsRequest request = new GetSettingsRequest().indices("your_index");
GetSettingsResponse response = client.indices().getSettings(request, RequestOptions.DEFAULT);
String numberOfShards = response.getSetting("your_index", "index.number_of_shards");

8. 安全问题

问题: 安全漏洞或未授权访问。

解决方法:
- 启用安全: 使用 X-Pack Security 或其他安全插件。
- 最小权限原则: 为用户配置适当的权限。
- 监控和警报: 启用监控,并设置警报系统以便在出现安全问题时及时响应。

9. 网络问题

问题: 集群节点间通信问题。

解决方法:
- 网络配置检查: 确保所有节点的网络配置正确,没有防火墙或其他网络设备阻止节点间通信。
- 使用专用网络: 如果可能,为 ES 集群使用专用网络。

10. 版本不兼容

问题: 升级后的版本不兼容。

解决方法:
- 渐进升级: 按照官方推荐的升级路径逐步升级。
- 备份数据: 在任何升级操作前备份数据。

// 获取 ES 版本信息
MainResponse response = client.info(RequestOptions.DEFAULT);
Version version = response.getVersion();

对于所有这些问题,查看 Elasticsearch 的日志文件通常是诊断问题的第一步。日志文件中的错误和警告信息可以提供问题的直接线索。此外,Elasticsearch 的社区和文档是解决问题的宝贵资源。记住,改变配置或硬件之前,最好先在非生产环境中测试。

Elasticsearch日常使用小结

【Q】离线告警,有IP已离线

描述:离线告警,有IP已离线,请关注;
影响:节点离线瞬间,最多出现1分钟抖动(master宕机)。若存在副本则业务无影响;若无副本,集群会存在不可用索引,请及时检查业务监控

可能会出现好多yellow的索引,等恢复后,离线的节点会自动加回来

还有联系运维就行

【Q】测试环境两个索引关联查询, 贼慢

经研究发现不是代码问题,由于公司降本增效,
测试环境集群是很多项目共用的,然后这个集群分片数太多,
换个集群数据重新写入下就OK了...
见笑了...

【Q】想缩容节点, 怎么操作嘞

首先在es平台查看当前的集群磁盘使用情况,
根据未来的大概使用情况的评估再去决定缩容多少,
还有参考节点的规格都是多大的磁盘(这边一般1T),
操作后, 缩容前会将数据迁移到其他节点,数据迁移完后才会去真正缩容节点

还有集群最小3个节点哟...

【Q】可以存储嵌套对象吗

可以的, 但是我们这里的平台需要通过自定义导入添加

【Q】测试环境一些好久没使用的索引突然发现全红了

发现迁移过集群, 重建下索引就可以了

【Q】返回 SearchPhaseExecutionException: all shards failed 异常

查询报这个错, 搞点数据就行了...

【Q】有一个数据节点的磁盘空间远大于其他节点,并且实际使用空间很低,可能通过加小节点,缩容大节点处理吗?

本次处理:节点都是固定规格的,可以想办法共用其他集群


在 Elasticsearch 中,如果你有一个数据节点的磁盘空间远大于其他节点,并且实际使用空间很低,你可能想要重新平衡集群以更有效地利用资源。以下是一些步骤和策略,你可以考虑实施以缩容大节点并通过添加更小的节点来平衡集群:

1. 添加新的小节点
首先,你可以向集群中添加一个或多个小的数据节点。确保这些新节点的配置(如 CPU、内存、磁盘类型和网络连接)与现有节点相似,以保持集群的均衡性。

2. 重新分配分片
添加新节点后,Elasticsearch 会自动开始重新分配分片以平衡集群。你可以通过以下方式帮助这个过程:

- 使用 Shard Allocation Filtering:
  你可以通过设置分片分配过滤来鼓励 Elasticsearch 将分片从大节点移动到新的小节点。例如,你可以使用 `_cluster/settings` API 更新集群设置,为大节点设置一个权重,使其更不可能接收新分片。

- 手动迁移分片:
  如果自动平衡不符合你的需求,你也可以手动迁移分片。通过 `_cluster/reroute` API,你可以强制将特定分片从一个节点移动到另一个节点。

3. 缩容大节点
如果你希望缩小大节点的磁盘空间,这通常意味着你需要停止节点,更改硬件配置,然后重新加入集群。这是一个影响较大的操作,需要谨慎执行,并确保在操作期间集群的副本分片可以保持数据的完整性和可用性。
4. 优化分片数量和大小

在 Elasticsearch 中,拥有适当大小和数量的分片对于集群性能和资源利用率至关重要。如果你注意到某个节点的磁盘使用率特别低,这可能是因为分片没有被均匀分布,或者整个集群的分片数量太多或太少。

- 调整分片数量:你可以通过修改索引的分片数量来优化存储分布。对于新索引,你可以在创建时指定分片数量。对于现有索引,你需要使用重新索引(reindex)或分片调整大小(shrink/expand)的操作来调整分片数量。

- 合并(force merge)分片:如果你的索引是静态的(不再写入新数据),你可以使用 force merge 操作来减少每个索引的分片数,这样可以提高查询效率并减少磁盘空间的使用。

5. 调整分片分配策略

Elasticsearch 允许你通过各种设置来控制分片是如何在集群中分配的。你可以使用分片分配感知(Shard Allocation Awareness)和强制感知(Forced Awareness)来确保分片均匀地分布在不同的节点上。

- 使用分片分配感知:你可以配置集群,使其意识到节点的物理位置或其他属性,从而在不同的组或区域之间平衡分片。

- 使用强制分片分配:在某些情况下,你可能需要强制集群将分片分配到特定的节点或节点组。这可以通过集群设置来实现。

6. 监控和调整

在对集群进行任何重大更改后,密切监控集群的性能和状态是非常重要的。使用 Elasticsearch 的监控工具,如 Kibana 中的 Stack Monitoring 功能,可以帮助你了解更改的影响。

- 监控集群状态:确保集群状态保持在绿色,这意味着所有的分片都已正确分配且没有问题。

- 监控节点和索引性能:查看各个节点的负载,以及索引和查询的性能。

7. 清理和维护

定期清理未使用的索引和优化现有索引可以帮助你更好地利用硬件资源。

- 删除旧索引:定期删除不再需要的旧数据可以释放大量空间。

- 使用 ILM(索引生命周期管理):自动化索引的生命周期管理,包括创建、优化和删除索引。

8. 考虑使用热/温/冷架构

如果你的数据访问模式具有明显的热度层次,可以考虑实施热/温/冷数据架构。在这种架构下,你可以将新数据(热数据)放在性能更高的节点上,而将访问频率较低的数据(冷数据)迁移到成本更低的存储上。

9. 考虑 Elasticsearch 的最佳实践

确保你遵循 Elasticsearch 的最佳实践,包括合理的分片大小(通常建议每个分片保持在几十 GB 的大小),以及合理的分片和副本数量。

10. 集群重新平衡后的维护

在集群重新平衡之后,持续监控并根据需要调整分片分配策略和集群配置。务必确保所有变更不会影响到集群的稳定性和性能。

在进行任何重大更改之前,最好先在测试环境中模拟这些更改,以确保它们不会对生产环境造成意外的副作用。此外,始终确保在进行任何可能影响数据完整性的操作之前备份你的数据。

【Q】一个索引文件建议最大分片数有限制吗?

一个索引文件建议最大分片数有限制吗?当在每个分片数据都写满的情况下,分片数到达某个什么值的时候,才会做周期生成索引文件。

还是周期索引和分片数量的多少,没有任何关系,只是周期索引更便于清理数据和根据业务的增长,调整以后索引文件的分片数?


在 Elasticsearch 中,索引的分片数量应根据数据量、硬件资源、查询负载以及数据的生命周期来合理设置。没有硬性规定说一个索引的分片数量上限是多少,但是确实有一些最佳实践和考虑因素:

分片大小的建议

- 每个分片的大小:通常建议每个分片的大小保持在几十 GB(比如 20GB 到 50GB)以内。这样做的原因是为了保持分片的管理和恢复的效率。

分片数量的考虑

- 硬件资源:分片数量过多可能会导致节点上的文件句柄使用过多、内存压力增大以及集群状态信息过于庞大,这些都可能影响集群的性能和稳定性。

- 查询性能:每个查询都需要在所有相关分片上执行,如果分片数量过多,可能会降低查询性能。

- 数据写入:数据写入时,如果分片数过多,每个分片处理的文档数较少,可能会造成资源浪费。

周期索引的使用

周期索引(如按天、按周或按月分割的索引)通常与分片数量无直接关系,它们主要是为了:

- 数据管理:周期索引使得数据的删除变得简单,你可以直接删除整个索引而不是删除特定日期范围内的文档。
  
- 性能优化:随着时间的推移,你可以根据数据量和查询模式调整新周期索引的分片数量。

- 热/温/冷架构:周期索引可以方便地实现不同数据温度的存储策略,如将旧的索引移动到成本更低的存储。

索引生成的触发

索引的生成通常是由以下因素触发的:

- 时间周期:基于时间的索引策略会按照预定的周期创建新索引。
- 数据量:达到一定数据量后,可以选择创建新索引。
- 性能和维护:为了优化性能和维护的方便,可以定期创建新索引。

结论

总的来说,分片数量的多少和周期索引的创建是两个独立的考虑点,它们都应该基于你的业务需求和实际的使用情况来决定。周期索引是一种数据管理策略,而分片数量的设置则涉及到性能和资源利用的优化。在实践中,你可能需要根据索引的大小、查询的复杂性以及数据增长的速度来调整这些设置。

文章来源:https://blog.csdn.net/libusi001/article/details/135277081
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。