跳至内容

如何对我的 OpenSearch Service 集群上的高 CPU 使用率问题进行故障排除?

3 分钟阅读
0

我的数据节点显示我的 Amazon OpenSearch Service 集群上的 CPU 使用率高。

简短描述

要对集群上的高 CPU 使用率问题进行故障排除,请执行以下操作:

  • 使用自动化运行手册来确定 CPU 使用率高的原因。
  • 使用异常检测来识别模式。
  • 使用节点热点线程 API 来了解您的资源使用情况。
  • 检查写入操作或批量 API 线程池。
  • 检查搜索线程池。
  • 检查 Apache Lucene 合并线程池。
  • 检查 Java 虚拟机 (JVM) 内存压力。
  • 查看您的分片策略。
  • 扩展您的集群。
  • 优化您的查询。

最佳做法是将 CPU 使用率保持在足够低的水平,以使 OpenSearch Service 能够执行其任务。CPU 使用率持续较高的集群可能会遇到性能问题。OpenSearch Service 无法响应过载的集群,您会收到超时请求。

解决方法

使用自动化运行手册

先决条件:确保您拥有运行运行手册所需的 AWS Identity and Access Management (IAM) 权限。有关详细信息,请参阅 AWSSupport-TroubleshootOpenSearchHighCPU 中的所需的 IAM 权限

运行 AWSSupport-TroubleshootOpenSearchHighCPU AWS Systems Manager Automation 运行手册以对 OpenSearch Service 中的高 CPU 使用率问题进行故障排除。

输出显示以下信息:

  • 热点线程
  • 正在运行的任务
  • 域中每个节点的线程池统计信息
  • 有关域中节点的信息,按其 CPU 使用率排序
  • 对每个数据节点及其磁盘空间进行分片分配
  • 运行状况和有关 OpenSearch Service 域运行状况的信息

使用运行手册的输出来确定 CPU 使用率高的原因。

使用异常检测来识别模式

要在潜在问题导致中断之前将其识别,请使用 OpenSearch Service 中的异常检测来自动检测 CPU 使用率等指标中的异常模式。有关详细信息,请参阅教程: 使用异常检测功能检测高 CPU 使用率

使用节点热点线程 API

如果您的 OpenSearch Service 集群中持续存在 CPU 峰值,请运行以下命令来查看集群中所有节点的信息:

GET/_nodes/hot_threads

输出的长度取决于您的 OpenSearch Service 集群中正在运行的节点数。有关节点热点线程 API 的详细信息,请参阅 OpenSearch 网站上的节点热点线程 API

输出示例:

GET _nodes/hot_threads
100.0% (131ms out of 500ms) cpu usage by thread 'opensearch[abc][search][T#62]'
10/10 snapshots sharing following 10
elements sun.misc.Unsafe.park(Native Method)
java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
java.util.concurrent.LinkedTransferQueue.awaitMatch(LinkedTransferQueue.java:737)

java.util.concurrent.LinkedTransferQueue.xfer(LinkedTransferQueue.java:647)

java.util.concurrent.LinkedTransferQueue.take(LinkedTransferQueue.java:1269)

org.opensearch.common.util.concurrent.SizeBlockingQueue.take(SizeBlockingQueue.java:162)

java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)

java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)

java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)

您还可以使用 cat 节点 API 查看当前的资源使用率细分情况。要查看 CPU 使用率最高的节点,请运行以下命令:

GET _cat/nodes?v&s=cpu:desc

输出的最后一列显示节点名称。有关 cat 节点 API 的详细信息,请参阅 OpenSearch 网站上的 CAT 节点 API

然后,为 CPU 使用率高的节点运行以下命令:

GET _nodes/node_id/hot_threads

**注意:**请将 node_id 替换为节点 ID。

输出显示了节点中 CPU 使用率最高的 OpenSearch Service 进程。如果您在输出中看到 Apache Lucene 合并线程,请参阅检查 Apache Lucene 合并线程池进行故障排除。

输出示例:

percentage of cpu usage by thread 'opensearch[nodeName][thread-name]'

检查写入操作或批量 API 线程池

如果您收到 "429" 错误消息,则集群的批量索引请求可能过多。当您的集群中持续出现 CPU 峰值时,OpenSearch Service 会拒绝批量索引请求。

写入线程池管理索引请求,其中包括批量 API 操作。要检查您的域是否因批量索引请求过多而承受压力,请查看 IndexingRate Amazon CloudWatch 指标

如果集群的批量索引请求过多,请执行以下操作:

  • 减少集群上的批量请求数量。
  • 减小每个批量请求的大小,以便节点可以更高效地进行处理。
  • 如果使用 Logstash 将数据上传到您的 OpenSearch Service 集群,请减少批量大小或 Worker 数量。
  • 如果集群的摄取速度变慢,请水平或垂直扩展集群

查看搜索线程池

CPU 使用率高的搜索线程池表明,搜索查询会使您的 OpenSearch Service 集群不堪重负。一个长时间运行的查询可能会使您的集群不堪重负。您的集群执行的查询次数增加也会影响您的搜索线程池。

要检查单个查询是否会增加 CPU 使用率,请运行以下命令:

GET _tasks?actions=*search&detailed

任务管理 API 显示在您的集群上运行的所有活动搜索查询。有关详细信息,请参阅 OpenSearch 网站上的列表任务 API

在输出中,查看 description 字段以确定正在运行的查询。running_time_in_nanos 字段显示查询的运行时间。

输出示例:

{    "nodes": {
        "U4M_p_x2Rg6YqLujeInPOw": {
            "name": "U4M_p_x",
            "roles": [
                "data",
                "ingest"
            ],
            "tasks": {
                "U4M_p_x2Rg6YqLujeInPOw:53506997": {
                    "node": "U4M_p_x2Rg6YqLujeInPOw",
                    "id": 53506997,
                    "type": "transport",
                    "action": "indices:data/read/search",
                    "description": """indices[*], types[], search_type[QUERY_THEN_FETCH], source[{"size":10000,"query":{"match_all":{"boost":1.0}}}]""",
                    "start_time_in_millis": 1541423217801,
                    "running_time_in_nanos": 1549433628,
                    "cancellable": true,
                    "headers": {}
                }
            }
        }
    }
}

**注意:**对于搜索任务,任务管理 API 输出仅包含描述字段。

要降低 CPU 使用率,请运行以下命令取消 CPU 使用率高的搜索查询:

POST _tasks/U4M_p_x2Rg6YqLujeInPOw:53506997/_cancel

**注意:**请将 U4M_p_x2Rg6YqLujeInPOw:53506997 替换为您的任务 ID。

上述查询将任务标记为 cancelled(已取消),然后释放依赖的 AWS 资源。如果您的集群上运行多个查询,请使用 POST 命令取消每个查询,直到您的集群恢复正常状态。

要防止出现 CPU 峰值,最佳做法是在查询正文中设置超时值。有关详细信息,请参阅 OpenSearch 网站上的搜索设置。要验证活动查询的数量是否减少,请查看 SearchRate CloudWatch 指标

**注意:**在 OpenSearch Service 集群中同时取消所有活动搜索查询时,客户端应用程序端可能会出错。

查看 Apache Lucene 合并线程池

OpenSearch Service 使用 Apache Lucene 来索引和搜索集群上的文档。当您创建新的分片区段时,Apache Lucene 会运行合并操作以减少每个分区的有效区段数并移除已删除的文档。有关详细信息,请参阅 Elastic 网站上的合并设置

如果 Apache Lucene 合并线程影响您的 CPU 使用率,请运行以下命令来增加索引的 refresh_interval 设置:

PUT /your-index-name/_settings
{
  "index": {
    "refresh_interval": "value"
  }
}

**注意:**请将 value 替换为新的请求间隔。此更新会减慢集群区段的创建速度。有关详细信息,请参阅 OpenSearch 网站上的刷新索引 API

当集群将索引迁移到 UltraWarm 存储空间时,您的 CPU 使用率可能会增加。UltraWarm 迁移通常使用强制合并 API 操作,该操作可能会占用大量 CPU 资源。有关详细信息,请参阅 OpenSearch 网站上的强制合并 API

要检查 UltraWarm 迁移,请运行以下命令:

GET _ultrawarm/migration/_status?v

检查 JVM 内存压力

检查集群节点中 Java 堆的 JVM 内存压力百分比。在以下日志示例中,JVM 处于建议范围内,但长时间运行的垃圾回收会对集群造成影响:

[2022-06-28T10:08:12,066][WARN ][o.o.m.j.JvmGcMonitorService] [515f8f06f23327e6df3aad7b2863bb1f] [gc][6447732] overhead, spent [9.3s]collecting in the last [10.2s]

要解决 JVM 内存压力高的问题,请参阅如何对 OpenSearch Service 集群上的高 JVM 内存压力问题进行故障排除?

查看您的分片策略

根据集群大小,您的集群性能可能会由于分片过多而降低。最佳做法是每 GiB 的 Java 堆最多 25 个分片

默认情况下,OpenSearch Service 的分片策略为 5:1,其中每个索引有五个主分片。在每个索引中,每个主分片都有自己的副本。OpenSearch Service 会自动将主分片和副本分片分配给单独的数据节点,并确保在出现故障时有备份。

要重新分配分片,请参阅如果我的 OpenSearch Service 集群中的分片分配不均匀,如何重新平衡?

扩展集群

确保集群有足够的 CPU、内存和磁盘空间来满足您的需求。如果您的应用程序执行大型查询或频繁写入,请调整集群或节点的大小以满足性能需求

此外,使用专用主控节点来提高集群的稳定性和弹性,尤其是在大型部署中。此配置将集群管理职责从数据节点中移除。

优化您的查询

大量聚合、通配符查询(例如前导通配符)和正则表达式 (regex) 查询可能会导致 CPU 使用率飙升。要诊断这些查询,请查看 OpenSearch 慢速日志

相关信息

如何提高我的 OpenSearch Service 集群上的索引性能?

如何解决 OpenSearch Service 中的搜索或写入拒绝问题?

调整 OpenSearch Service 域的大小