上次更新时间:2021 年 4 月 5 日
我的 Amazon Elasticsearch Service (Amazon ES) 集群遇到搜索延迟峰值问题。如何排查并解决搜索延迟峰值问题?
简短描述对于搜索请求,往返时间的计算方法如下:
Round trip = Time the query spends in the query phase + time in the fetch phase + time spent in the queue + network latency
Amazon CloudWatch 上的 SearchLatency 指标为您提供查询在查询阶段花费的时间。
您可以采取很多问题排查步骤来排查 Amazon ES 群集中的搜索延迟峰值问题,包括:
检查集群上预置的资源是否不足 使用 CloudWatch 中的 ThreadpoolSearchRejected 指标检查搜索拒绝情况 使用搜索慢日志和配置文件 API 解决任何 504 网关超时错误 解决方法 检查集群上预置的资源是否不足如果您在 Amazon ES 集群上预置的资源不足,则可能会遇到搜索延迟峰值。使用以下最佳实践来确保您预置了足够的资源。
1.使用 Amazon CloudWatch 查看集群的 CPUUtilization 指标和 JVMMemory 压力,以确认它们在建议的阈值范围内。有关更多信息,请参阅建议的 CloudWatch 警报。
2.使用 Node Stats API 获取集群的节点级别统计数据:
GET /_nodes/stats
在输出中,检查以下部分:缓存、fielddata 和 jvm。多次运行此 API,并延迟一些时间,以比较输出。
3.Amazon ES 使用文件系统缓存来提出更快的搜索请求。查看 NodeStats API 输出以了解缓存移出。输出中的大量缓存移出意味着缓存大小不足以满足请求的需求。在这种情况下,考虑使用具有更多内存的更大节点。
4.对包含高度唯一值的字段执行聚合可能会导致堆使用量增加。如果聚合查询已在使用中,则搜索操作将使用 FieldData。FieldData 还用于对脚本中的字段值进行排序和访问。FieldData 移出取决于 indices.fielddata.cache.size 文件的大小,这占 JVM 堆空间的 20%。移出在超过缓存时开始。
有关排查高 JVM 内存问题的更多信息,请参阅如何排查 Amazon ES 集群上的高 JVM 内存压力问题?
要排查 CPU 使用率较高的问题,请参阅如何排查我的 Amazon ES 集群上的 CPU 使用率较高问题?
使用 CloudWatch 中的 ThreadpoolSearchRejected 指标检查搜索拒绝情况要使用 CloudWatch 检查搜索拒绝情况,请遵照如何解决 Amazon ES 中的搜索或写入拒绝问题?中的步骤
使用搜索慢日志识别长时间运行的查询使用慢日志可以识别长时间运行的查询和某个查询花在特定分区上的时间。您可以为查询阶段设置阈值,然后为每个索引获取阶段。有关设置慢日志的更多信息,请参阅查看 Amazon ES 慢日志。务必设置您的搜索查询的 "profile":true,以获得您的查询在查询阶段所花时间的详细分解。
注意:如果您将日志记录的阈值设置为非常低的值,那么 JVM 内存压力可能会增加。这可能会导致更频繁的垃圾回收,从而提高 CPU 使用率并增加集群上的延迟。记录更多查询也可能会增加成本。配置文件 API 的输出可能很长,而且还会显著增加任何搜索查询的开销。
解决任何 504 网关超时错误从 Amazon ES 集群的应用程序日志中,您可以看到单个请求的特定 HTTP 错误代码。有关解决 HTTP 504 网关超时错误的更多信息,请参阅我如何防止 Amazon ES 中出现 HTTP 504 网关超时错误?
注意:必须启用错误日志才能识别特定的 HTTP 错误代码。有关 HTTP 错误代码的更多信息,请参阅查看 Amazon ES 错误日志。
可能导致高搜索延迟的其他因素
还有许多其他因素可能导致高搜索延迟。使用以下提示进一步排查高搜索延迟的问题:
频繁或长时间运行的垃圾收集活动可能会导致搜索性能问题。垃圾收集活动可能会暂停线程,并提高搜索延迟。有关其他信息,请参阅 Elasticsearch 网站上的管理 Elasticsearch 的托管堆。 预置 IOPS(或 i3 实例)可能会帮助您消除任何 Amazon Elastic Block Store (Amazon EBS) 瓶颈。在大多数情况下,您不需要它们。最佳做法是您在直接移动到 i3 之前测试 i3 节点和 r5 节点之间的性能。 具有太多分区的集群可能会导致资源使用率增加,即使集群处于非活动状态也是如此。太多的分片会降低查询性能。尽管增加副本分区计数可以帮助您实现更快的搜索速度,但请确保给定节点上的分区不超过 1000 个。此外,请确保分区大小介于 10GiB 和 50GiB 之间。理想情况下,节点上的最大分区数应为堆 * 20。 太多的分段或删除的文档太多可能会影响搜索性能。在这种情况下,对只读索引使用强制合并可能有所帮助。如果您的用例允许,请增加活动索引的内部刷新。有关更多信息,请参阅 Elasticsearch 网站上的 Lucene 对已删除文档的处理。 如果您的集群位于 VPC 中,请考虑在同一 VPC 中运行应用程序。 请考虑为只读数据使用 UltraWarm 节点或热数据节点。热存储可以为索引和搜索新数据提供最快的性能。但是,如果需要将大量只读数据存储到 Amazon ES 上,则 UltraWarm 节点是一种经济高效的方式。对于您当前未向其执行写入操作或无需相同性能的索引,UltraWarm 可以显著降低每 GiB 数据的成本。 测试您的工作负载,了解是否可以在所有节点上使用正在搜索的数据并从中获益。有些应用程序从这种方法中受益,尤其是当集群上的索引很少时。为此,请增加副本分区的数量。请记住,这可能会增加索引延迟。此外,您可能需要额外的 Amazon EBS 存储来容纳要添加的副本。这将增加您的 EBS 卷成本。 尽可能少地搜索字段,避免脚本和通配符查询。有关更多信息,请参阅 Elasticsearch 网站上的调整搜索速度。 对于具有许多分区的索引,您可以使用自定义路由来帮助加快搜索速度。自定义路由可确保只查询保存数据的分区,而不是将请求广播到索引的所有分区。有关更多信息,请参阅 Elasticsearch 网站上的自定义您的文档路由。