任务管理器故障排除

编辑

Kibana 中的许多服务都使用任务管理器,例如警报、操作、报告和遥测。这些服务中出现意外行为可能是源自任务管理器的下游问题。

本页介绍了如何解决您在使用任务管理器时可能遇到的常见问题。如果此处未描述您的问题,请查看以下 GitHub 存储库中的未解决问题

有问题?请在讨论论坛中联系我们。

计划间隔较小的任务运行延迟

编辑

问题:

任务计划每 2 秒运行一次,但似乎运行延迟。

解决方案:

任务管理器按照 xpack.task_manager.poll_interval 设置指定的频率轮询任务,默认值为 3 秒。这意味着,如果任务使用的计划小于此设置,则任务可能会运行延迟。

您可以调整 xpack.task_manager.poll_interval 设置。但是,这将为集群中的 Kibana 和 Elasticsearch 实例增加额外的负载,因为它们将执行更多查询。

任务运行延迟

编辑

问题:

任务管理器中潜在问题的最常见症状是任务似乎运行延迟。例如,重复性任务可能以不一致的频率运行,或者在计划时间后很长时间才运行。

解决方案:

默认情况下,Kibana 以每 3 秒 10 个任务的速率轮询任务。

如果计划同时运行许多任务,则待处理的任务将在 Elasticsearch 中排队。然后,每个 Kibana 实例以每次最多 10 个任务的速率,每 3 秒间隔轮询待处理的任务。队列中的待处理任务可能会超过此容量,并因此运行延迟。

这种类型的延迟称为漂移。漂移的根本原因取决于具体的使用情况,并且没有解决漂移的硬性规定。

例如

  • 如果漂移是由相对于集群中 Kibana 实例的可用容量,并发任务过多引起的,则扩展集群的吞吐量。
  • 如果漂移是由运行时间过长的任务超出其计划频率引起的,则重新配置相关任务。

有关识别正确解决方案的分步说明,请参阅诊断漂移的根本原因

通常通过调整部署规模以更好地适应您的使用情况来解决漂移。有关扩展任务管理器的详细信息,请参阅扩展指南

诊断漂移的根本原因

编辑

此功能为技术预览版,可能会在未来的版本中更改或删除。Elastic 将努力修复任何问题,但技术预览版中的功能不受官方 GA 功能的支持 SLA 的约束。

以下指南通过理解运行状况监控端点的输出来帮助您识别漂移的根本原因。

通过分析输出的不同部分,您可以评估解释部署中漂移的不同理论。

检索 Kibana 实例任务管理器的最新监控运行状况统计信息

$ curl -X GET api/task_manager/_health

API 返回以下内容

{
  "id": "15415ecf-cdb0-4fef-950a-f824bd277fe4",
  "timestamp": "2021-02-16T11:38:10.077Z",
  "status": "OK",
  "last_update": "2021-02-16T11:38:09.934Z",
  "stats": {
    "configuration": {
      "timestamp": "2021-02-16T11:29:05.055Z",
      "value": {
        "request_capacity": 1000,
        "monitored_aggregated_stats_refresh_rate": 60000,
        "monitored_stats_running_average_window": 50,
        "monitored_task_execution_thresholds": {
          "default": {
            "error_threshold": 90,
            "warn_threshold": 80
          },
          "custom": {}
        },
        "poll_interval": 3000,
        "max_workers": 10
      },
      "status": "OK"
    },
    "runtime": {
      "timestamp": "2021-02-16T11:38:09.934Z",
      "value": {
        "polling": {
          "last_successful_poll": "2021-02-16T11:38:09.934Z",
          "last_polling_delay": "2021-02-16T11:29:05.053Z",
          "duration": {
            "p50": 13,
            "p90": 128,
            "p95": 143,
            "p99": 168
          },
          "claim_conflicts": {
            "p50": 0,
            "p90": 0,
            "p95": 0,
            "p99": 0
          },
          "claim_mismatches": {
            "p50": 0,
            "p90": 0,
            "p95": 0,
            "p99": 0
          },
          "result_frequency_percent_as_number": {
            "Failed": 0,
            "NoAvailableWorkers": 0,
            "NoTasksClaimed": 80,
            "RanOutOfCapacity": 0,
            "RunningAtCapacity": 0,
            "PoolFilled": 20
          }
        },
        "drift": {
          "p50": 99,
          "p90": 1245,
          "p95": 1845,
          "p99": 2878
        },
        "load": {
          "p50": 0,
          "p90": 0,
          "p95": 10,
          "p99": 20
        },
        "execution": {
          "duration": {
            "alerting:.index-threshold": {
              "p50": 95,
              "p90": 1725,
              "p95": 2761,
              "p99": 2761
            },
            "alerting:xpack.uptime.alerts.monitorStatus": {
              "p50": 149,
              "p90": 1071,
              "p95": 1171,
              "p99": 1171
            },
            "actions:.index": {
              "p50": 166,
              "p90": 166,
              "p95": 166,
              "p99": 166
            }
          },
          "persistence": {
            "recurring": 88,
            "non_recurring": 4,
            "ephemeral": 8
          },
          "result_frequency_percent_as_number": {
            "alerting:.index-threshold": {
              "Success": 100,
              "RetryScheduled": 0,
              "Failed": 0,
              "status": "OK"
            },
            "alerting:xpack.uptime.alerts.monitorStatus": {
              "Success": 100,
              "RetryScheduled": 0,
              "Failed": 0,
              "status": "OK"
            },
            "actions:.index": {
              "Success": 10,
              "RetryScheduled": 0,
              "Failed": 90,
              "status": "error"
            }
          }
        }
      },
      "status": "OK"
    },
    "workload": {
      "timestamp": "2021-02-16T11:38:05.826Z",
      "value": {
        "count": 26,
        "task_types": {
          "alerting:.index-threshold": {
            "count": 2,
            "status": {
              "idle": 2
            }
          },
          "actions:.index": {
            "count": 14,
            "status": {
              "idle": 2,
              "running": 2,
              "failed": 10
            }
          },
          "alerting:xpack.uptime.alerts.monitorStatus": {
            "count": 10,
            "status": {
              "idle": 10
            }
          },
        },
        "schedule": [
          ["10s", 2],
          ["1m", 2],
          ["60s", 2],
          ["5m", 2],
          ["60m", 4],
          ["3600s", 1],
          ["720m", 1]
        ],
        "non_recurring": 18,
        "owner_ids": 0,
        "overdue": 10,
        "overdue_non_recurring": 10,
        "estimated_schedule_density": [0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 3, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0],
        "capacity_requirements": {
          "per_minute": 6,
          "per_hour": 28,
          "per_day": 2
        }
      },
      "status": "OK"
    },
    "capacity_estimation": {
      "timestamp": "2021-02-16T11:38:06.826Z",
      "value": {
        "observed": {
          "observed_kibana_instances": 1,
          "max_throughput_per_minute_per_kibana": 200,
          "max_throughput_per_minute": 200,
          "minutes_to_drain_overdue": 1,
          "avg_recurring_required_throughput_per_minute": 28,
          "avg_recurring_required_throughput_per_minute_per_kibana": 28,
          "avg_required_throughput_per_minute": 28,
          "avg_required_throughput_per_minute_per_kibana": 28
        },
        "proposed": {
          "min_required_kibana": 1,
          "provisioned_kibana": 1,
          "avg_recurring_required_throughput_per_minute_per_kibana": 28,
          "avg_required_throughput_per_minute_per_kibana": 28
        }
      }
      "status": "OK"
    }
  }
}

评估配置

编辑

理论:Kibana 配置为以较低的速率轮询任务。

诊断:评估运行状况统计信息,您可以在 stats.configuration.value 下看到以下输出

{
  "request_capacity": 1000,
  "monitored_aggregated_stats_refresh_rate": 60000,
  "monitored_stats_running_average_window": 50,
  "monitored_task_execution_thresholds": {
    "default": {
      "error_threshold": 90,
      "warn_threshold": 80
    },
    "custom": {}
  },
  "poll_interval": 3000, 
  "max_workers": 10 
}

poll_interval 设置为默认值 3000 毫秒

max_workers 设置为默认值 10 个工作进程

您可以从此输出推断出 Kibana 实例每 3 秒轮询一次工作,并且可以运行 10 个并发任务。

现在假设 stats.configuration.value 下的输出如下所示

{
  "request_capacity": 1000,
  "monitored_aggregated_stats_refresh_rate": 60000,
  "monitored_stats_running_average_window": 50,
  "monitored_task_execution_thresholds": {
    "default": {
      "error_threshold": 90,
      "warn_threshold": 80
    },
    "custom": {}
  },
  "poll_interval": 60000, 
  "max_workers": 1 
}

poll_interval 设置为 60000 毫秒,远高于默认值

max_workers 设置为 1 个工作进程,远低于默认值

您可以从此输出推断出 Kibana 实例每分钟只轮询一次工作,并且一次只选取一个任务。此吞吐量不太可能支持关键任务服务,例如警报或报告,并且任务通常会运行延迟。

出现这种配置的原因可能有两种

  • 这些设置已手动配置,可以通过重新配置这些设置来解决。有关详细信息,请参阅任务管理器设置
  • Kibana 已降低自身的吞吐量,以应对 Elasticsearch 集群上的过度负载。

    任务管理器配备了反应式自愈机制,以响应 Elasticsearch 中与负载相关的错误增加。此机制将增加 poll_interval 设置(降低其查询 Elasticsearch 的速率),并减少 max_workers(减少其针对 Elasticsearch 执行的操作数量)。一旦错误率降低,这些设置将再次逐步调高,将其恢复为配置的设置。

    可以通过在 Kibana 服务器日志中搜索诸如此类的消息来识别此场景

    Max workers configuration is temporarily reduced after Elasticsearch returned 25 "too many request" error(s).

    需要对 Elasticsearch 集群经历的高错误率进行更深入的调查。

评估运行时

编辑

理论:Kibana 没有按照应有的频率进行轮询

诊断:评估运行状况统计信息,您会在 stats.runtime.value.polling 下看到以下输出

{
  "last_successful_poll": "2021-02-16T11:38:09.934Z", 
  "last_polling_delay": "2021-02-14T11:29:05.053Z",
  "duration": { 
    "p50": 13,
    "p90": 128,
    "p95": 143,
    "p99": 168
  },
  "claim_conflicts": { 
    "p50": 0,
    "p90": 0,
    "p95": 0,
    "p99": 2
  },
  "claim_mismatches": {
    "p50": 0,
    "p90": 0,
    "p95": 0,
    "p99": 0
  },
  "result_frequency_percent_as_number": { 
    "Failed": 0,
    "NoAvailableWorkers": 0,
    "NoTasksClaimed": 80,
    "RanOutOfCapacity": 0,
    "RunningAtCapacity": 0,
    "PoolFilled": 20
  }
}

确保上次成功轮询周期在过去不超过 poll_interval 的几倍完成。

确保轮询周期的持续时间通常低于 100 毫秒。更长的持续时间是可能的,但出乎意料。

确保集群中的 Kibana 实例没有遇到高版本的冲突率。

确保大多数轮询周期都会产生积极的结果,例如 RunningAtCapacityPoolFilled

您可以从此输出推断出 Kibana 实例正在定期轮询。此评估基于以下内容

  • last_successful_poll 与根目录处的 timestamp(值为 2021-02-16T11:38:10.077Z)进行比较,您可以在其中看到上次轮询周期发生在健康状况监控 API 公开监控统计信息之前 1 秒。
  • last_polling_delay 与根目录处的 timestamp(值为 2021-02-16T11:38:10.077Z)进行比较,您可以在其中看到上次轮询周期延迟发生在 2 天前,这表明 Kibana 实例没有经常发生冲突。
  • durationp50 表明,至少 50% 的轮询周期最多需要 13 毫秒才能完成。
  • 评估 result_frequency_percent_as_number

    • 80% 的轮询周期完成时未声明任何任务(表明没有任何逾期任务)。
    • 20% 的任务完成时任务管理器声明了随后执行的任务。
    • 没有轮询周期最终占用所有可用的工作进程,因为 RunningAtCapacity 的频率为 0%,这表明任务管理器中有足够的容量来处理工作负载。

所有这些统计信息都作为运行平均值进行跟踪,这意味着它们给出了某个时间段的快照(默认情况下,Kibana 最多跟踪 50 个周期),而不是给出完整的历史记录。

假设 stats.runtime.value.polling.result_frequency_percent_as_number 下的输出如下所示

{
  "Failed": 30, 
  "NoAvailableWorkers": 20, 
  "NoTasksClaimed": 10,
  "RanOutOfCapacity": 10, 
  "RunningAtCapacity": 10, 
  "PoolFilled": 20
}

30% 的轮询周期失败,这是一个很高的失败率。

20% 的轮询周期被跳过,因为任务管理器没有剩余的容量来运行任务。

10% 的轮询周期导致任务管理器声明的任务多于其有能力运行的任务。

10% 的轮询周期导致任务管理器声明的任务数量与它有能力运行的任务数量完全相同。

您可以从此输出推断出任务管理器不健康,因为失败率很高,并且任务管理器正在提取其没有能力运行的任务。分析 Kibana 服务器日志应揭示导致高错误率和容量问题的根本问题。

20% 的高 NoAvailableWorkers 率表明许多任务的运行时间长于 poll_interval。有关分析长时间任务执行持续时间的详细信息,请参阅长时间运行的任务理论。

理论:Kibana 按照应有的频率进行轮询,但频率不足以跟上工作负载

诊断:评估健康状况统计信息,您可以在 stats.runtime.value 下看到以下 driftload 的输出。

{
  "drift": { 
    "p50": 99,
    "p90": 1245,
    "p95": 1845,
    "p99": 2878
  },
  "load": { 
    "p50": 0,
    "p90": 0,
    "p95": 10,
    "p99": 20
  },
}

drift 向我们展示至少 95% 的任务在计划时间的 2 秒内运行。

load 向我们展示任务管理器至少 90% 的时间处于空闲状态,并且从未使用超过其可用工作线程的 20%。

您可以从这些统计信息中推断出,此 Kibana 具有充足的容量,并且您可能遇到的任何延迟都不太可能通过扩展吞吐量来解决。

假设 driftload 的输出如下:

{
  "drift": { 
    "p50": 2999,
    "p90": 3845,
    "p95": 3845.75,
    "p99": 4078
  },
  "load": { 
    "p50": 80,
    "p90": 100,
    "p95": 100,
    "p99": 100
  }
}

drift 向我们展示所有任务都在其计划时间之后 3 到 4 秒运行。

load 向我们展示,任务管理器至少有一半时间以 80% 的负载运行。

您可以从这些统计信息中推断出,此 Kibana 正在使用其大部分容量,但似乎大部分时间都能跟上工作进度。此评估基于以下几点:

  • loadp90 为 100%,p50 也相当高,为 80%。这意味着几乎没有回旋余地,并且工作量的激增可能会导致任务管理器超出其容量。
  • 任务在其计划时间后不久运行,这是预期的。 poll_interval3000 毫秒通常会经历介于 03000 毫秒之间的一致漂移。 p50 drift2999 表明有改进的空间,并且您可以从更高的吞吐量中受益。

有关通过调整您的扩展策略来实现更高吞吐量的详细信息,请参阅扩展指南

理论:任务运行时间过长,超出其计划时间

诊断处理计划工作负载的吞吐量不足理论分析了一个假设场景,其中漂移和负载都异常高。

假设另一种情况,其中 drift 很高,但 load 不高,例如以下情况:

{
    "drift": { 
        "p50": 9799,
        "p90": 83845,
        "p95": 90328,
        "p99": 123845
    },
    "load": { 
        "p50": 40,
        "p90": 75,
        "p95": 80,
        "p99": 100
    }
}

drift 显示大多数(如果不是全部)任务都至少晚 32 秒运行。

load 显示,在大多数情况下,您有能力运行更多并发任务。

在前面的场景中,任务运行时间太晚,但您有足够的容量来运行更多并发任务。高容量允许 Kibana 并发运行多个不同的任务。如果任务在下次计划运行时已经运行,Kibana 将避免第二次运行它,而是等待第一次执行完成。

如果任务的执行时间长于其计划的节奏,那么该任务将始终超出并经历较高的漂移。例如,假设一个任务计划每 3 秒执行一次,但需要 6 秒才能完成。它将持续受到至少 3 秒的漂移影响。

在此假设场景中评估健康状况统计信息,您会在 stats.runtime.value.execution.duration 下看到以下输出:

{
  "alerting:.index-threshold": { 
    "p50": 95,
    "p90": 1725,
    "p95": 2761,
    "p99": 2761
  },
  "alerting:.es-query": { 
    "p50": 7149,
    "p90": 40071,
    "p95": 45282,
    "p99": 121845
  },
  "actions:.index": {
    "p50": 166,
    "p90": 166,
    "p95": 166,
    "p99": 166
  }
}

50% 的支持索引阈值警报的任务在不到 100 毫秒内完成。

50% 的支持 Elasticsearch 查询警报的任务在 7 秒内完成,但至少 10% 的任务需要超过 40 秒。

您可以从这些统计信息中推断出,任务管理器经历的高漂移很可能是由于运行时间较长的 Elasticsearch 查询警报造成的。

解决此问题取决于具体情况,并且因情况而异。在前面的示例中,可以通过修改这些警报中的查询以使其更快,或者通过提高 Elasticsearch 吞吐量来加快退出查询速度来解决此问题。

理论:任务需要多次尝试才能成功

诊断:高错误率可能导致任务看起来运行延迟,而实际上它按时运行,但经历了高失败率。

评估前面的健康状况统计信息,您会在 stats.runtime.value.execution.result_frequency_percent_as_number 下看到以下输出:

{
  "alerting:.index-threshold": { 
    "Success": 100,
    "RetryScheduled": 0,
    "Failed": 0,
    "status": "OK"
  },
  "alerting:xpack.uptime.alerts.monitorStatus": {
    "Success": 100,
    "RetryScheduled": 0,
    "Failed": 0,
    "status": "OK"
  },
  "actions:.index": { 
    "Success": 8,
    "RetryScheduled": 0,
    "Failed": 92,
    "status": "error" 
  }
}

100% 的支持索引阈值警报的任务成功完成。

92% 的支持 ES 索引操作的任务未能完成。

支持 ES 索引操作的任务已超出默认的 monitored_task_execution_thresholds 错误 配置。

您可以从这些统计信息中推断出,大多数支持 ES Index Kibana 操作的 actions:.index 任务都失败了。解决该问题需要更深入地调查 Kibana 服务器日志,其中记录了确切的错误,并解决这些特定错误。

理论:非循环和临时任务的激增消耗了可用容量的很高比例

诊断:任务管理器使用临时非循环任务来在多个 Kibana 实例之间加载平衡操作。此外,Kibana 可以通过执行临时任务来为昂贵的操作分配资源。临时任务在操作上与非循环任务相同,但不会持久化,也无法在 Kibana 实例之间进行负载平衡。

评估前面的健康状况统计信息,您会在 stats.runtime.value.execution.persistence 下看到以下输出:

{
  "recurring": 88, 
  "non_recurring": 4, 
  "ephemeral": 8 
},

88% 的执行任务是循环任务

4% 的执行任务是非循环任务

8% 的执行任务是临时任务

您可以从这些统计信息中推断出,大多数执行由 88% 的循环任务组成。您可以使用 execution.persistence 统计信息来评估已消耗容量的比率,但就其本身而言,您不应就可用容量的充足性做出假设。

要评估容量,您应该对照 stats.runtime.value 下的 load 来评估这些统计信息。

{
    "load": { 
        "p50": 40,
        "p90": 40,
        "p95": 60,
        "p99": 80
    }
}

您可以从这些统计信息中推断出,任务管理器耗尽容量的情况非常罕见,因此容量可能足以处理非循环和临时任务的数量。

假设您有另一种情况,您会在 stats.runtime.value.execution.persistence 下看到以下输出:

{
  "recurring": 60, 
  "non_recurring": 30, 
  "ephemeral": 10 
},

60% 的执行任务是循环任务

30% 的执行任务是非循环任务

10% 的执行任务是临时任务

您可以从这些统计信息中推断出,即使大多数执行是循环任务,但很大比例的执行是非循环和临时任务,占 40%。

评估 stats.runtime.value 下的 load,您会看到以下内容:

{
    "load": { 
        "p50": 70,
        "p90": 100,
        "p95": 100,
        "p99": 100
    }
}

您可以从这些统计信息中推断出,此 Kibana 实例耗尽容量的情况很常见。鉴于非循环和临时任务的高比率,可以合理地评估 Kibana 集群中的容量不足以处理任务量。

请记住,这些统计信息让您了解了某一时刻的情况,即使最近几分钟容量不足,但这在其他使用较少非循环或临时任务的时间可能并非如此。我们建议您跟踪这些统计信息,并确定这些任务的来源,然后再对您的基础设施进行全面更改。

评估工作负载

编辑

预测部署可能需要支持任务管理器的所需吞吐量是困难的,因为功能可以以各种计划节奏调度不可预测数量的任务。

运行状况监控提供了统计信息,可以更轻松地监控现有吞吐量的充足性。通过评估工作负载,可以估算所需的吞吐量,该吞吐量在遵循任务管理器扩展指南时使用。

在前面的示例中评估前面的健康状况统计信息,您会在 stats.workload.value 下看到以下输出:

{
  "count": 26, 
  "task_types": {
    "alerting:.index-threshold": {
      "count": 2, 
      "status": {
        "idle": 2
      }
    },
    "actions:.index": {
      "count": 14,
      "status": {
        "idle": 2,
        "running": 2,
        "failed": 10 
      }
    },
    "alerting:xpack.uptime.alerts.monitorStatus": {
      "count": 10,
      "status": {
        "idle": 10
      }
    },
  },
  "non_recurring": 0, 
  "owner_ids": 1, 
  "schedule": [ 
    ["10s", 2],
    ["1m", 2],
    ["90s", 2],
    ["5m", 8]
  ],
  "overdue_non_recurring": 0, 
  "overdue": 0, 
  "estimated_schedule_density": [ 
    0, 1, 0, 0, 0, 1, 0, 1, 0, 1,
    0, 0, 0, 1, 0, 0, 1, 1, 1, 0,
    0, 3, 0, 0, 0, 1, 0, 1, 0, 1,
    0, 0, 0, 1, 0, 0, 1, 1, 1, 0
  ],
  "capacity_requirements": { 
    "per_minute": 14,
    "per_hour": 240,
    "per_day": 0
  }
}

系统中有 26 个任务,包括常规任务、循环任务和失败的任务。

有 2 个 idle 索引阈值警报任务,这意味着它们计划在将来的某个时间运行。

在支持 ES 索引操作的 14 个任务中,有 10 个失败,2 个正在运行。

队列中没有非循环任务。

有一个任务管理器正在主动执行任务。可能还有其他空闲的任务管理器,但它们此时此刻并未主动执行任务。

所有计划的循环任务的直方图显示,2 个任务计划每 10 秒运行一次,2 个任务计划每分钟运行一次,等等。

没有过期的非循环任务。非循环任务通常计划立即执行,因此过期的非循环任务通常是系统拥堵的症状。

没有过期的任务,这意味着现在应该运行的所有任务都已经运行

此直方图显示了在即将到来的 20 个轮询周期中计划运行的任务。直方图表示整个部署,而不仅仅是此 Kibana 实例。

处理系统中循环任务所需的容量。这些是存储桶,而不是汇总的总和,我们建议评估容量估算部分,而不是自己评估这些存储桶。

workload 部分汇总了整个集群的工作负载,列出了系统中的任务、其类型、计划和当前状态。

您可以从这些统计信息中推断出,默认部署应该足够了。此评估基于以下几点:

  • 估计的计划密度较低。
  • 相对于默认容量,系统中没有太多任务。

假设 stats.workload.value 的输出如下所示:

{
  "count": 2191, 
  "task_types": {
    "alerting:.index-threshold": {
      "count": 202,
      "status": {
        "idle": 183,
        "claiming": 2,
        "running": 19
      }
    },
    "alerting:.es-query": {
      "count": 225,
      "status": {
        "idle": 225,
      }
    },
    "actions:.index": {
      "count": 89,
      "status": {
        "idle": 24,
        "running": 2,
        "failed": 63
      }
    },
    "alerting:xpack.uptime.alerts.monitorStatus": {
      "count": 87,
      "status": {
        "idle": 74,
        "running": 13
      }
    },
  },
  "non_recurring": 0,
  "owner_ids": 1,
  "schedule": [ 
    ["10s", 38],
    ["1m", 101],
    ["90s", 55],
    ["5m", 89],
    ["20m", 62],
    ["60m", 106],
    ["1d", 61]
  ],
  "overdue_non_recurring": 0,
  "overdue": 0, 
  "estimated_schedule_density": [  
    10, 1, 0, 10, 0, 20, 0, 1, 0, 1,
    9, 0, 3, 10, 0, 0, 10, 10, 7, 0,
    0, 31, 0, 12, 16, 31, 0, 10, 0, 10,
    3, 22, 0, 10, 0, 2, 10, 10, 1, 0
  ],
  "capacity_requirements": {
    "per_minute": 329, 
    "per_hour": 4272, 
    "per_day": 61 
  }
}

系统中有 2,191 个任务。

计划的任务分布在各种节奏中。

计划密度显示您预计会超过默认的 10 个并发任务。

在每分钟的时间范围内,有 329 个任务执行循环发生。

在每小时的时间范围内,有 4,273 个任务执行循环发生。

在每天的时间范围内,有 61 个任务执行循环发生。

您可以从此输出中推断出工作负载的几个重要属性:

  • 您的系统中有许多任务,确保这些任务按计划节奏运行将需要注意任务管理器吞吐量。
  • 评估高频任务(以几分钟或更短的频率重复发生的任务),您必须支持大约每分钟 330 个任务执行的吞吐量(每 10 秒 38 个 + 每分钟 101 个)。
  • 评估中频任务(以一小时或更短的频率重复发生的任务),您必须支持每小时超过 4,272 个任务执行的额外吞吐量(每 90 秒 55 个 + 每 5 分钟 89 个 + 每 20 分钟 62 个 + 每小时 106 个)。 您可以通过将这些任务视为每分钟额外的 70 - 80 个任务来平均计算每小时所需的吞吐量。
  • 评估估计的计划密度,有些周期会并发运行多达 31 个任务,并且在这些周期旁边,还有空闲周期。您可以期望任务管理器在空闲周期中平衡这些任务的负载,但这不会留下太多容量来处理将来可能安排的新任务的峰值。

这些粗略的计算为您提供了所需吞吐量的下限,即至少每分钟 410 个任务,以确保定期任务在其计划的时间执行。此吞吐量不包括可能已安排的非定期任务,也不包括将来可能安排的任务(定期或其他)。

鉴于这些推断的属性,可以安全地假设具有默认设置的单个 Kibana 实例 将不会 提供所需的吞吐量。 可以通过水平扩展,添加几个 Kibana 实例来实现。

有关扩展任务管理器的详细信息,请参阅扩展指南

评估容量估计

编辑

任务管理器不断评估其运行时操作和工作负载。这使任务管理器能够粗略估计其容量的充足性。

顾名思义,这些是基于历史数据的估计值,不应将其用作预测。在更改基础架构之前,应与详细的 运行状况监控 统计信息一起评估这些估计值。这些估计假设所有 Kibana 实例的配置均相同。

我们建议在遵循任务管理器扩展指南时使用这些估计值。

在前面的示例中评估运行状况统计信息,您可以在 stats.capacity_estimation.value 下看到以下输出

{
  "observed": {
    "observed_kibana_instances": 1, 
    "minutes_to_drain_overdue": 1, 
    "max_throughput_per_minute_per_kibana": 200,
    "max_throughput_per_minute": 200, 
    "avg_recurring_required_throughput_per_minute": 28, 
    "avg_recurring_required_throughput_per_minute_per_kibana": 28,
    "avg_required_throughput_per_minute": 28, 
    "avg_required_throughput_per_minute_per_kibana": 28
  },
  "proposed": {
    "min_required_kibana": 1, 
    "provisioned_kibana": 1, 
    "avg_recurring_required_throughput_per_minute_per_kibana": 28,
    "avg_required_throughput_per_minute_per_kibana": 28
  }
}

这些估计假设有一个 Kibana 实例正在主动执行任务。

根据过去的吞吐量,系统中过期的任务可以在 1 分钟内执行完毕。

假设集群中的所有 Kibana 实例的配置都与此实例相同,则最大可用吞吐量为每分钟 200 个任务。

平均而言,系统中的定期任务在历史上需要每分钟 28 个任务的吞吐量。

平均而言,无论是否定期,系统中的任务在历史上需要每分钟 28 个任务的吞吐量。

一个 Kibana 实例应该足以运行当前的定期工作负载。

我们建议等待工作负载发生变化,然后再配置额外的 Kibana 实例。

capacity_estimation 部分由两个子部分组成

  • observed 通过观察历史运行时和工作负载统计信息来估计当前容量
  • proposed 估计基准 Kibana 集群大小以及在此类部署策略下的预期吞吐量

您可以从这些估计中推断出当前系统利用率不足,并且有足够的容量来处理比当前更多的任务。

假设另一种情况,您在 stats.capacity_estimation.value 下看到以下输出

{
  "observed": {
    "observed_kibana_instances": 2, 
    "max_throughput_per_minute_per_kibana": 200,
    "max_throughput_per_minute": 400, 
    "minutes_to_drain_overdue": 12, 
    "avg_recurring_required_throughput_per_minute": 354, 
    "avg_recurring_required_throughput_per_minute_per_kibana": 177, 
    "avg_required_throughput_per_minute": 434, 
    "avg_required_throughput_per_minute_per_kibana": 217
  },
  "proposed": {
    "min_required_kibana": 2, 
    "provisioned_kibana": 3, 
    "avg_recurring_required_throughput_per_minute_per_kibana": 118, 
    "avg_required_throughput_per_minute_per_kibana": 145 
  }
}

这些估计假设有两个 Kibana 实例正在主动执行任务。

当前系统中最大可用吞吐量为每分钟 400 个任务。

根据过去的吞吐量,系统中过期的任务应在 12 分钟内执行完毕。

平均而言,系统中的定期任务在历史上需要每分钟 354 个任务的吞吐量。

平均而言,每个 Kibana 实例利用其容量的每分钟 177 个任务来执行定期任务。

平均而言,系统中的任务在历史上需要每分钟 434 个任务的吞吐量。

系统估计至少需要两个 Kibana 实例才能运行当前的定期工作负载。

系统建议配置三个 Kibana 实例来处理工作负载。

配置第三个 Kibana 实例后,每个实例用于执行定期任务的容量应从每分钟 177 个任务降至 118 个任务。

考虑到历史临时任务执行情况,我们估计每个 Kibana 实例所需的吞吐量将从每分钟 217 个任务降至 145 个,一旦配置了第三个 Kibana 实例。

通过这些估计进行评估,我们可以推断出系统的一些有趣属性

  • 这些估计是基于集群中有两个 Kibana 实例的假设得出的。 此数字基于最近几分钟内主动执行任务的 Kibana 实例的数量。 有时,如果 Kibana 实例保持空闲状态,此数字可能会波动,因此建议对照您对系统的了解验证这些估计值。
  • 似乎有过多的过期任务,需要执行 12 分钟才能赶上积压的工作。这不包括在这 12 分钟内可能过期的任务。尽管这种拥塞可能是暂时的,但系统也可能始终配置不足,并且可能永远无法完全清空积压的工作。
  • 评估工作负载中的定期任务,系统平均需要每分钟 354 个任务的吞吐量才能按时执行任务,这低于估计的最大吞吐量每分钟 400 个任务。但是,一旦我们考虑到历史吞吐量,我们估计所需的吞吐量为每分钟 434 个任务。这表明,从历史上看,大约 20% 的任务是临时非定期任务,其规模比定期任务更难预测。

您可以从这些估计中推断出当前系统的容量不足,并且至少需要一个额外的 Kibana 实例才能跟上工作负载。

有关扩展任务管理器的详细信息,请参阅扩展指南

在 Elasticsearch 中禁用内联脚本时,任务管理器无法运行

编辑

问题:

任务未运行,服务器日志包含以下错误消息

[warning][plugins][taskManager] Task Manager cannot operate when inline scripts are disabled in {es}

解决方案:

内联脚本是任务管理器正常运行的硬性要求。 要启用内联脚本,请参阅 Elasticsearch 文档,了解配置允许的脚本类型设置

如果任务的 runAt 在过去,我该怎么办?

编辑

问题:

任务的属性 runAt 在过去。

解决方案:

在将其声明为无望之前,请稍等片刻,因为任务管理器可能只是在工作上落后了。 您应该查看 Kibana 日志,看看您能找到哪些与任务管理器相关的日志。 在健康的环境中,当 Kibana 启动时,您应该看到一条日志行,指示任务管理器已成功启动

server log [12:41:33.672] [info][plugins][taskManager][taskManager] TaskManager is identified by the Kibana UUID: 5b2de169-2785-441b-ae8c-186a1936b17d

如果您看到该消息并且没有其他与任务管理器相关的错误,则很可能是任务管理器运行良好,只是还没有机会拾取该任务。 另一方面,如果 runAt 严重过期,则值得寻找其他任务管理器或与警报相关的错误,因为其他地方可能出了问题。 值得查看状态字段,因为它可能已失败,这将解释为什么它没有被拾取,或者它可能正在运行,这意味着该任务可能只是一个非常耗时的任务。

如果任务标记为失败,我该怎么办?

编辑

问题:

标记为失败的任务。

解决方案:

从广义上讲,警报框架旨在通过在将来重新安排新运行来优雅地处理任务失败的情况。 如果未能发生这种情况,则意味着底层实现中出现了一些问题,这是意料之外的。 理想情况下,您应该尝试查找与此规则及其任务相关的任何日志行,并使用它们来帮助我们进一步调查。

任务管理器 Kibana 日志

编辑

在某些情况下,任务管理器会将日志行写入 Kibana 日志。 以下是一些常见的日志行及其含义。

任务管理器已耗尽可用工作线程

server log [12:41:33.672] [info][plugins][taskManager][taskManager] [Task Ownership]: Task Manager has skipped Claiming Ownership of available tasks at it has ran out Available Workers.
server log [12:41:33.672] [warn][plugins][taskManager][taskManager] taskManager plugin is now degraded: Task Manager is unhealthy - Reason: setting HealthStatus.Error because of expired hot timestamps

此日志消息告诉我们,任务管理器未能跟上其已被分配完成的大量工作。 这可能意味着规则的运行频率未达到预期(例如,不是每 5 分钟运行一次,而是每 7-8 分钟运行一次)。

默认情况下,任务管理器限制为 10 个任务,可以通过使用 xpack.task_manager.capacity 配置在 kibana.yml 文件中设置更高的数字来增加此限制。 重要的是要记住,在任何给定时间运行的任务数量越多,Kibana 和 Elasticsearch 的负载就越大; 仅当增加环境中的负载有意义时才更改此设置。

解决此问题的另一种方法是告诉工作线程以更高的速率运行,而不是添加更多工作线程,这将使用 xpack.task_manager.poll_interval 进行配置。此值指示任务管理器检查是否有更多工作要完成的频率,并使用毫秒(默认情况下为 3000,这意味着间隔为 3 秒)。

在更改这些数字中的任何一个之前,强烈建议调查任务管理器无法跟上速度的原因 - 系统中是否存在异常大量的规则? 规则是否经常失败,迫使任务管理器不断重新运行它们? Kibana 是否处于高负载状态? 可能存在各种各样的问题,而这些问题都不应通过简单地更改这些配置来解决。

任务 TaskType 在尝试运行时失败

server log [12:41:33.672] [info][plugins][taskManager][taskManager] Task TaskType "alerting:example.always-firing" failed in attempt to run: Unable to load resource ‘/api/something’

这条日志消息告诉我们,当任务管理器运行我们的某个规则时,该任务出错并因此失败。在这种情况下,我们可以知道失败的规则类型是 alerting:example.always-firing,并且失败原因是无法加载资源 '/api/something'。这是一个人为设计的示例,但总的来说,如果您看到格式类似的消息,它会告诉您很多关于问题可能出在哪里。

例如,在这种情况下,我们应该会看到警报框架本身发出相应的日志行,说明该规则失败。您应该在 Kibana 日志中查找与下面日志行相似的行(可能在任务管理器日志行之前不久):

执行规则 "27559295-44e4-4983-aa1b-94fe043ab4f9" 导致错误:无法加载资源 ‘/api/something’

这将确认错误确实发生在规则本身(而不是任务管理器中),并且可以帮助我们精确定位失败规则的特定 ID:27559295-44e4-4983-aa1b-94fe043ab4f9

现在我们可以使用该 ID,通过 http 端点查找该规则的配置和当前状态,以帮助调查可能导致该问题的原因。