# 监控和指标

指标提供了对集群内部发生的事情的洞察。它们是监控和调试的宝贵资源。\
Alluxio 设置了一个基于[Prometheus官方指标库](https://github.com/prometheus/client_java)的可配置指标系统。\
该指标系统以 Prometheus 的公开格式来陈列指标。

Alluxio 的指标被划分为根据 Alluxio 组件相对应的不同实例。当前支持以下实例：

* Coordinator: Alluxio coordinator 进程。
* Worker: Alluxio worker 进程。
* FUSE 进程: Alluxio FUSE进程。

## 使用

向目标 Alluxio 进程的`/metrics/`发送 HTTP 请求，获取所有指标的快照。

```shell
# 从 Alluxio 进程获取指标
$ curl <COORDINATOR_HOSTNAME>:<COORDINATOR_WEB_PORT>/metrics/
$ curl <WORKER_HOSTNAME>:<WORKER_WEB_PORT>/metrics/
$ curl <FUSE_HOSTNAME>:<FUSE_WEB_PORT>/metrics/
```

例如，对于本地进程：

```shell
# 从默认的19999端口获取本地 coordinator 指标
$ curl 127.0.0.1:19999/metrics/
# 从默认的30000端口获取本地 worker 指标
$ curl 127.0.0.1:30000/metrics/
# 从默认的49999端口获取本地 fuse 指标
$ curl 127.0.0.1:49999/metrics/
```

[Metrics](/ee-ai-cn/ai-3.6/reference/metrics.md)页面提供了更详细的指标的描述。

## 集成

### Kubernetes Operator

Operator 支持使用内置的 Prometheus 和 Grafana 构建集群。默认情况下 Prometheus 和 Grafana 都会开启。\
Grafana 可以被关闭，通过设置 `enabled` 字段为 false。Prometheus 不能被关闭。\
配置和 Grafana 模板已经包括在内。只需在 `AlluxioCluster` 配置中设置以下开关：

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  grafana:
    enabled: false
```

### Grafana

Grafana 是一个用于可视化时间序列数据的指标分析和可视化软件。\
您可以使用 Grafana 更好地将 Alluxio 收集的各种指标可视化展示。\
该软件允许用户更容易地查看 Alluxio 中内存、存储和完成运行操作的变化。

Grafana 支持从 Prometheus 可视化数据。以下步骤可以帮助您基于 Grafana 和 Prometheus 轻松构建 Alluxio 监控系统。

1. 下载 Alluxio 的 Grafana 模板 JSON 文件：[alluxio-ai-dashboard-template.json](https://alluxio-binaries.s3.amazonaws.com/artifactsBundle/ee/AI-3.6-12.0.0/alluxio-ai-dashboard-template.json)
2. 将模板 JSON 文件导入以创建仪表板。请参阅此[示例](https://grafana.com/docs/grafana/latest/dashboards/export-import/#importing-a-dashboard)以导入仪表板。
3. 以自定义名称，例如 *prometheus-alluxio*，将 Prometheus 数据源添加到 Grafana。请参阅[教程](https://grafana.com/docs/grafana/latest/datasources/add-a-data-source/#add-a-data-source)以获取导入仪表板的帮助。

如果您的 Grafana 仪表板看起来像下面的截图，那么您已成功构建了监控系统。

<figure><img src="/files/35dw51XNPVZZPlUnzY1D" alt=""><figcaption></figcaption></figure>

默认情况下，只有 *集群* 行被展开，以显示当前状态的摘要。*进程* 行显示资源消耗和与 JVM 相关的指标，可以在顶部通过服务或实例进行过滤。\
其他行显示某些组件的详细信息，可以通过实例进行过滤。

#### 通过节点主机名访问Grafana

Grafana 会将在其主机的 8080 端口上公开其服务。使用 kubectl 获取主机名：

```shell
kubectl -n alx-ns get pod $(kubectl -n alx-ns get pod -l app.kubernetes.io/component=grafana --no-headers -o custom-columns=:metadata.name) -o jsonpath='{.spec.nodeName}'
```

假设主机名是`foo.kubernetes.org`，那么您可以在以下地址访问Grafana服务：

```
http://foo.kubernetes.org:8080/
```

#### 通过端口转发访问Grafana

如果因网络问题无法通过节点主机名直接访问 Grafana，可以使用端口转发将 Grafana 的端口映射到本地，从而通过本地端口进行访问。

执行 `kubectl port-forward` 命令进行端口转发

```console
kubectl -n alx-ns port-forward $(kubectl -n alx-ns get pod -l app.kubernetes.io/component=grafana -o jsonpath="{.items[0].metadata.name}") 3000:3000
```

您可以通过以下地址在本地直接访问 Grafana 服务：

```
http://localhost:3000
```

## Prometheus

使用示例 `prometheus.yml` 配置 Prometheus 服务以抓取相关指标。注意，如果需要适配内置的 Grafana，则不应更改 `job_name`。

```yaml
global:
  scrape_interval: 60s

scrape_configs:
  - job_name: "prometheus"
    static_configs:
      - targets: [ 'localhost:9090' ]
  - job_name: "coordinator"
    static_configs:
      - targets: [ '<COORDINATOR_HOSTNAME>:<COORDINATOR_WEB_PORT>' ]
  - job_name: "worker"
    static_configs:
      - targets: [ '<WORKER_HOSTNAME>:<WORKER_WEB_PORT>' ]
  - job_name: "fuse"
    static_configs:
      - targets: [ '<FUSE_HOSTNAME>:<FUSE_WEB_PORT>' ]
```

如果要在 Kubernetes 中启动独立的 Prometheus 服务，请参考以下代码片段，额外从 Kubernetes 环境中提取 Pod 注解。

```yaml
scrape_configs:
  - job_name: 'prometheus'
    kubernetes_sd_configs:
      - role: pod
        namespaces:
          names:
            - default
    tls_config:
      insecure_skip_verify: true
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
        action: keep
        regex: (?:alluxio)
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_component]
        action: keep
        regex: prometheus
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod_name
      - source_labels: [__meta_kubernetes_pod_node_name]
        action: replace
        target_label: node
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
        action: replace
        target_label: cluster_name

  - job_name: 'coordinator'
    kubernetes_sd_configs:
      - role: pod
        namespaces:
          names:
            - default
    tls_config:
      insecure_skip_verify: true
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
        action: keep
        regex: (?:alluxio)
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_component]
        action: keep
        regex: coordinator
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod_name
      - source_labels: [__meta_kubernetes_pod_node_name]
        action: replace
        target_label: node
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
        action: replace
        target_label: cluster_name

  - job_name: 'worker'
    kubernetes_sd_configs:
      - role: pod
        namespaces:
          names:
            - default
    tls_config:
      insecure_skip_verify: true
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
        action: keep
        regex: (?:alluxio)
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_component]
        action: keep
        regex: worker
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod_name
      - source_labels: [__meta_kubernetes_pod_node_name]
        action: replace
        target_label: node
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
        action: replace
        target_label: cluster_name

  - job_name: 'fuse'
    kubernetes_sd_configs:
      - role: pod
        namespaces:
          names:
            - default
    tls_config:
      insecure_skip_verify: true
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
        action: keep
        regex: (?:alluxio)
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_component]
        action: keep
        regex: (csi-)?fuse
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: namespace
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: pod_name
      - source_labels: [__meta_kubernetes_pod_node_name]
        action: replace
        target_label: node
      - source_labels: [__meta_kubernetes_pod_label_app_kubernetes_io_instance]
        action: replace
        target_label: cluster_name
```

请再次注意，如果需要适配内置的 Grafana，`scrape_configs` 中的 `job_name` 需要保持不变。

以下是所需的元数据：

```yaml
labels:
  app.kubernetes.io/instance: alluxio # 用于区分不同的 alluxio 集群
  app.kubernetes.io/component: worker # alluxio 集群的组件，包括 coordinator、worker 和 fuse 和 csi-fuse。
annotations:
  prometheus.io/scrape: "true"
  # 值应与组件的端口匹配。默认情况下，coordinator 为 19999，worker 为 30000，fuse 为 49999
  prometheus.io/port: "30000"
  prometheus.io/path: "/metrics/"
```

### Datadog

Alluxio 会导出 Prometheus 格式的指标，这使得 Datadog 可以直接和Alluxio集成。

1. 确保 Datadog 可以访问在[Prometheus集成](#Prometheus)中列出的端口
2. 在 Datadog 配置文件的 `instances` 字段下增加多条 `prometheus_url` 配置

以下是从多个组件获取指标的配置片段：

```yaml
instances:
  - prometheus_url: <http://<alluxio-coordinator-instance>>:19999/metrics
  - prometheus_url: <http://<alluxio-worker-1-instance>>:30000/metrics
  - prometheus_url: <http://<alluxio-worker-2-instance>>:30000/metrics
  ...
```

按照以上步骤，就能让 Datadog 无缝地收集和监控 Alluxio 的指标，为您的 Alluxio 集群性能和健康状况提供深入分析与全面监控。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://documentation.alluxio.io/ee-ai-cn/ai-3.6/start/monitoring-and-metrics.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
