我如何解决 Amazon Elasticsearch Service 上的 Kibana 的“Courier 获取:m 个分区中的 n 个失败”错误?

上次更新时间:2019 年 8 月 23 日

当我尝试在 Amazon Elasticsearch Service (Amazon ES) 域上的 Kibana 中加载控制面板时,它返回如下错误:“错误:Courier 获取:60 个分区中的 5 个失败”。

注意:造成此错误的原因有很多。本文介绍一些常见的根本原因和解决方案。

简短描述

当您尝试在 Kibana 中加载控制面板时,Kibana 发送搜索请求至 Amazon ES 域。该搜索请求将路由至集群节点,该节点作为请求的协调节点。当协调节点未能完成搜索请求的获取阶段时,发生“Courier 获取:m 个分区中的 n 个失败”错误。通常有两类问题会导致此错误:

  • 持久性问题:映射冲突或未分配的分区。如果您的索引模式中有多个索引,且其中一些索引具有名称相同但映射类型不同的字段,您可能会收到 Courier 获取错误。如果您的集群处于红色状态,则表示至少有一个分区未分配。由于 Elasticsearch 无法从未分配的分区中获取文档,处于红色状态的集群会引发 Courier 获取错误。如果您仍然收到 Courier 获取错误且错误消息(“Courier 获取:m 个分区中的 n 个失败”)中的“n”值始终相同,则原因可能是持久性问题。重试或预置多个群集资源不会解决持久性问题。检查应用程序错误日志以了解问题排查建议。
  • 暂时性问题线程池拒绝、搜索超时现场数据断路器跳闸等等。当您的集群上没有足够的计算资源时,会发生这些问题。如果错误间歇性发生,且错误消息中的“n”值在每次发生错误时都不同,则原因可能是暂时性问题。您还可以监控 CPUUtilization、JVMMemoryPressure 和 ThreadpoolSearchRejected 等 Amazon Cloudwatch 指标,以确定造成 Courier 获取错误的是否是暂时性问题。

解决方法

启用域的应用程序错误日志。该日志可以帮助您确定暂时性问题和持久性问题的根本原因和解决方案。

持久性问题

以下示例显示的是持久性问题造成的 Courier 获取错误的一个日志条目。

注意:日志条目并未总是如此——您的日志条目可能会有所不同。

[2019-07-01T12:54:02,791][DEBUG][o.e.a.s.TransportSearchAction] [ip-xx-xx-xx-xxx] [1909731] Failed to execute fetch phase
org.elasticsearch.transport.RemoteTransportException: [ip-xx-xx-xx-xx][xx.xx.xx.xx:9300][indices:data/read/search[phase/fetch/id]]
Caused by: java.lang.IllegalArgumentException: Fielddata is disabled on text fields by default. 
Set fielddata=true on [request_departure_date] in order to load fielddata in memory by uninverting the inverted index.
Note that this can however use significant memory. Alternatively use a keyword field instead.

在此示例中,问题由 request_departure_date 字段造成。日志条目显示,您可以通过在索引设置中设置 fielddata=true 或使用关键字字段解决此问题。

暂时性问题

以下示例显示的是暂时性问题造成的 Courier 获取错误的一个日志条目。

注意:日志条目并未总是如此——您的日志条目可能会有所不同。

Caused by: org.elasticsearch.common.util.concurrent.EsRejectedExecutionException: rejected execution of org.elasticsearch.common.util.concurrent.TimedRunnable@26fdeb6f on QueueResizingEsThreadPoolExecutor
[name = __PATH__ queue capacity = 1000, min queue capacity = 1000, max queue capacity = 1000, frame size = 2000, targeted response rate = 1s, task execution EWMA = 2.9ms, adjustment amount = 50,
org.elasticsearch.common.util.concurrent.QueueResizingEsThreadPoolExecutor@1968ac53[Running, pool size = 2, active threads = 2, queued tasks = 1015, completed tasks = 96587627]]

在本示例中,问题由搜索线程池队列拒绝造成。要解决此问题,通过选择较大的实例类型向上扩展您的域。

大多数暂时性问题可以通过以下方法之一解决:

预置更多计算资源

  • 通过切换到更大的实例类型向上扩展您的域,或通过在集群中添加更多节点来水平扩展。有关更多信息,请参阅配置 Amazon ES 域
  • 确认您使用的实例类型适合您的使用案例。有关更多信息,请参阅选择实例类型并测试

降低查询的资源使用率

  • 确认您在遵照分区和集群架构的最佳实践。设计拙劣的集群无法使用所有的可用资源。当一些节点处于闲置状态时,另一些节点可能会过载。Elasticsearch 无法从过载的节点中获取文档。
  • 缩小您的查询范围。例如,如果您按时间范围查询,则缩小日期范围或通过在 Kibana 中配置索引模式来筛选结果。
  • 避免对大型索引执行选择*查询。相反,使用筛选条件查询部分索引并且尽可能少地搜索字段
  • 重建索引并减少分区的数量。您的 Elasticsearch 集群中包含的分区越多,您越有可能收到 Courier 获取错误。由于每个分区都有自己的资源分配和开销,大量的分区对集群造成了过大的压力。要减少您的集群中的分区数量,请参阅我的 Amazon Elasticsearch Service 域已很长时间停滞在“正在处理”状态

这篇文章对您有帮助吗?

我们可以改进什么?


需要更多帮助吗?