菜单
文档面包屑箭头 Grafana Loki面包屑箭头 管理面包屑箭头 自动扩缩容查询器
开源 本页面内容适用于开源版本。

通过自动扩缩容的查询器大规模管理不同工作负载

运行在 Kubernetes 上的 Loki 集群的微服务部署通常需要处理全天变化的工作负载。为了使 Loki 更易于运维并优化大规模运行 Loki 的成本,我们设计了一套资源来帮助你自动扩缩容 Loki 查询器。

先决条件

你需要将 Loki 作为一组微服务运行在 Kubernetes 中。你需要使用 query-scheduler。

我们推荐使用 Kubernetes Event-Driven Autoscaling (KEDA) 根据 Prometheus 指标配置自动扩缩容。请参考 部署 KEDA 以了解如何在 Kubernetes 集群中设置 KEDA。

扩缩容指标

由于查询器从 query-scheduler 队列拉取查询并在查询器工作节点上处理它们,因此你应该根据以下指标进行扩缩容:

  • 调度器队列大小。
  • 查询器中正在运行的查询。

query-scheduler 暴露了 `loki_query_scheduler_inflight_requests` 指标。它跟踪排队中的查询总数加上当前在查询器工作节点中运行的查询数量。以下查询可用于根据 inflight 请求对查询器进行扩缩容。

promql
sum(
  max_over_time(
    loki_query_scheduler_inflight_requests{namespace="loki-cluster", quantile="<Q>"}[<R>]
  )
)

使用分位数(Q)和范围(R)参数来微调指标。Q 越高,指标对短暂的峰值越敏感。随着 R 的增加,你可以减少指标随时间的变化。较高的 R 值有助于避免自动扩缩容器过于频繁地修改副本数量。

根据我们的经验,我们发现 Q 为 0.75 和 R 为 2 分钟的效果很好。你可以根据你的工作负载调整这些值。

集群容量规划

要扩缩容 Loki 查询,你需要配置以下设置:

  • 扩容和缩容阈值
  • 缩容稳定期
  • 查询器的最小和最大数量

查询器工作节点处理队列中的查询。你可以配置每个 Loki 查询器运行多个工作节点。为了预留工作能力余量来应对工作负载峰值,我们建议不要使用超过 75% 的工作节点。例如,如果你配置 Loki 查询器运行 6 个工作节点,则将阈值设置为 `floor(0.75 * 6) = 4`。

要确定你应该运行的最小查询器数量,请至少运行一个查询器,并确定系统在七天内 75% 的时间内处理的 inflight 请求的平均数量。查询器的目标利用率是 75%。因此,如果每个查询器使用 6 个工作节点,我们将使用以下查询:

promql
clamp_min(ceil(
    avg(
        avg_over_time(loki_query_scheduler_inflight_requests{namespace="loki-cluster", quantile="0.75"}[7d])
    ) / scalar(floor(vector(6 * 0.75)))
), 1)

要运行的最大查询器数量等于七天内 50% 的时间处理所有 inflight 请求所需的查询器数量。对于上一个示例,如果每个查询器运行 6 个工作节点,则将 inflight 请求除以 6。最终的查询将是:

promql
ceil(
    max(
        max_over_time(loki_query_scheduler_inflight_requests{namespace="loki-cluster", quantile="0.5"}[7d])
    ) / 6
)

为了尽量减少 Loki 在缩容后不久又扩容的情况,为缩容设置一个稳定窗口。

KEDA 配置

这个 KEDA ScaledObject 示例配置了 `loki-cluster` 命名空间中查询器部署的自动扩缩容。示例显示最小副本数设置为 10,最大副本数设置为 50。因为每个查询器运行 6 个工作节点,目标是使用其中 75% 的工作节点,所以阈值设置为 4。指标通过 `http://prometheus.default:9090/prometheus` 提供。我们配置了 30 分钟的稳定窗口。

yaml
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
  name: querier
  namespace: loki-cluster
spec:
  maxReplicaCount: 50
  minReplicaCount: 10
  scaleTargetRef:
    kind: Deployment
    name: querier
  triggers:
  - metadata:
      metricName: querier_autoscaling_metric
      query: sum(max_over_time(loki_query_scheduler_inflight_requests{namespace="loki-cluster", quantile="0.75"}[2m]))
      serverAddress: http://prometheus.default:9090/prometheus
      threshold: "4"
    type: prometheus
  advanced:
    horizontalPodAutoscalerConfig:
      behavior:
        scaleDown:
          stabilizationWindowSeconds: 1800

Prometheus 在达到容量上限时的告警

由于配置的最大值可能不足,Prometheus 告警可以帮助识别查询器数量长时间(例如,本例中的三小时 `3h`)达到配置的最大值的情况。

yaml
name: LokiAutoscalerMaxedOut
expr: kube_horizontalpodautoscaler_status_current_replicas{namespace=~"loki-cluster"} == kube_horizontalpodautoscaler_spec_max_replicas{namespace=~"loki-cluster"}
for: 3h
labels:
  severity: warning
annotations:
  description: HPA {{ $labels.namespace }}/{{ $labels.horizontalpodautoscaler }} has been running at max replicas for longer than 3h; this can indicate underprovisioning.
  summary: HPA has been running at max replicas for an extended time