# 管理 Coordinator

Alluxio 中的 Coordinator 服务充当分布式任务调度器和集群管理器。它负责编排后台操作，例如数据加载（load）和释放（free），确保这些任务在集群中可靠且高效地执行。

与传统的 Alluxio Master 不同，Coordinator 被设计为无状态且高可用的，利用 **etcd** 进行所有状态管理和协调。

## 1. 部署架构

Coordinator 服务被设计为无状态且高可用的，利用 **etcd** 进行所有状态管理和协调。该架构支持单节点和多节点（高可用）部署。

### 单节点 Coordinator

对于单节点 Coordinator 部署，您可以使用本地存储或 **etcd** 来存储作业元数据和状态。这两种选项都能确保作业历史记录在 Coordinator 重启后仍能保留。

1. **RocksDB (默认):** Coordinator 默认使用本地 RocksDB 存储。这适用于不需要高可用性的独立部署。

   ```properties
   alluxio.coordinator.job.meta.store.type=ROCKS
   ```
2. **Etcd (可选):** 您也可以将单节点 Coordinator 连接到 etcd 实例。如果您计划将来过渡到高可用 (HA) 设置，建议使用此选项。

   ```properties
   alluxio.coordinator.job.meta.store.type=ETCD
   ```

### 高可用 (HA) 架构

Coordinator 服务通过基于 etcd 的无状态设计实现高可用性 (HA)。

* **无状态 Coordinator：** 您可以在集群中部署多个 Coordinator 实例（节点）。由于它们不在本地存储有关作业队列或 Worker 分配的状态，任何 Coordinator 都可以处理任何任务。
* **Etcd 作为事实来源：** 所有作业元数据、状态（Waiting, Running, Finished）和 Worker 注册信息都存储在 etcd 中。
* **容错性：** 如果一个 Coordinator 实例发生故障，其他运行中的实例将继续处理 etcd 中的共享作业队列。调度功能本身没有“Leader”选举；所有 Coordinator 都积极参与处理作业。
* **故障转移：** Coordinator 可在 10 秒内完成故障转移。对于调度失败的作业，剩余存活节点之间会通过协调选择一个来处理。

#### 配置 HA

要启用 HA，只需部署多个 Coordinator pod 或进程，并确保它们都指向同一个 etcd 集群。

etcd 连接的关键配置属性：

```properties
# 启用 etcd 作为作业元数据存储
alluxio.coordinator.job.meta.store.type=ETCD

# Etcd 端点（逗号分隔）
alluxio.etcd.endpoints=http://etcd1:2379,http://etcd2:2379,http://etcd3:2379

# 可选：专门用于作业调度的独立 etcd 集群
# 如果未设置，默认为 alluxio.etcd.endpoints
alluxio.coordinator.scheduler.load.job.etcd.endpoints=http://job-etcd1:2379,http://job-etcd2:2379

# 协调器故障检测的超时时间
alluxio.coordinator.failure.detection.timeout=5s
```

## 2. 作业调度和生命周期

Coordinator 管理诸如 `load`（缓存预热）和 `free`（缓存释放）等长时间运行的操作。作业的生命周期完全通过 etcd 键（keys）进行管理。

### 作业队列机制

1. **提交：** 当用户提交作业时（例如，通过 CLI `alluxio load ...`），请求被转换为作业条目并添加到等待队列中。
2. **调度：** 活动的 Coordinator 从队列中获取作业。一次只有一个 Coordinator 可以认领特定作业，防止重复执行。
3. **执行：** Coordinator 将作业分解为任务并将其分发给可用的 Worker。
4. **完成：** 成功或失败后，Coordinator 更新作业状态为 **FINISHED**（或 **FAILED**）。

### 可靠性

该系统保证即使多个 Coordinator 尝试同时获取同一个作业，也能保持一致性。更改作业状态的操作是原子的。

## 3. 故障恢复

该系统旨在优雅地处理 Coordinator 故障。

### 自动恢复

由于作业状态持久化在 etcd 中，Coordinator 崩溃并不意味着作业数据丢失。但是，崩溃的 Coordinator 正在管理的作业需要被恢复。

* **检测：** 活动的 Coordinator 可以检测到处于 **RUNNING** 状态的“陈旧”作业，这些作业属于不再发送心跳或更新其状态的 Coordinator。
* **重新排队：** 存在机制将这些“孤立”的运行中作业恢复为 **WAITING** 状态，以便另一个健康的 Coordinator 可以接管它们。

### 手动恢复 (`job rerun`)

在由于复杂故障（例如，作业期间的网络分区或完全集群重启）导致作业卡住的情况下，或者在连续故障或完全故障的情况下，管理员可以手动干预以回收失败的作业。

`job rerun` 命令允许您重置 etcd 中的作业状态，有效地将其移回队列以进行重试。

```bash
# 重新运行可能卡住的特定 load 作业
bin/alluxio job rerun --path /data/my-dataset --type load

# 重新运行分配给特定（已失败）Coordinator 的所有作业
# 示例: /bin/alluxio job rerun --coordinator 192.168.1.10
bin/alluxio job rerun --coordinator <failed_coordinator_host>
```

> **注意：** 此命令直接与 etcd 交互以修改作业状态。

## 4. 负载均衡

负载均衡是 Coordinator 去中心化架构所固有的。

* **共享队列：** 所有 Coordinator 从 etcd 中的同一个共享全局队列消费。
* **随机轮询：** 为了防止“惊群效应”（即所有 Coordinator 在完全相同的毫秒轮询 etcd），轮询间隔包含随机抖动。
* **Worker 容量：** 在调度任务时，Coordinator 遵守单个 Worker 可以处理多少任务的限制（`alluxio.coordinator.scheduler.max.tasks.per.worker`）。即使有多个 Coordinator 活动，这也可以防止压垮特定的 Worker。

## 5. 配置和调优

您可以根据特定的工作负载和 etcd 容量微调 Coordinator 的行为。

| 属性                                                     | 默认值              | 描述                                                                                     |
| ------------------------------------------------------ | ---------------- | -------------------------------------------------------------------------------------- |
| `alluxio.coordinator.scheduler.etcd.max.retries`       | (varies)         | etcd 操作放弃前的最大重试次数。                                                                     |
| `alluxio.coordinator.scheduler.etcd.read.timeout`      | (varies)         | 从 etcd 读取的超时时间。                                                                        |
| `alluxio.coordinator.scheduler.etcd.write.timeout`     | (varies)         | 写入 etcd 的超时时间。                                                                         |
| `alluxio.coordinator.scheduler.interval.time`          | `2s`             | 调度间隔。较短的间隔可以更快地调度小型作业，但会增加 CPU 开销。                                                     |
| `alluxio.coordinator.scheduler.job.etcd.path`          | `/alluxio/jobs/` | etcd 中用于存储作业元数据的前缀目录。                                                                  |
| `alluxio.coordinator.scheduler.job.etcd.poll.interval` | `1s`             | Coordinator 检查 etcd 中新等待作业的频率。较低的值意味着更快的响应，但 etcd 的负载更高。                               |
| `alluxio.coordinator.scheduler.max.tasks.per.worker`   | `3`              | Worker 容量即为 Worker 的线程池限制。该配置决定了每个 Coordinator 能够在同一个 Worker 上同时调度多少个任务。               |
| `alluxio.coordinator.scheduler.waiting.job.capacity`   | `2000`           | 调度器中等待作业的容量限制。此配置用于防止 Coordinator 因调度过多作业而过载。                                          |
| `alluxio.job.batch.size`                               | `200`            | 调度器发送一个任务所包含的文件数量。较大的值会增加 worker 并发性，但可能超出 worker 的线程池大小。可以通过 CLI（`--batch-size`）手动覆盖。 |
| `alluxio.job.cleanup.interval`                         | `1H`             | 周期性清理 etcd 中已完成作业的时间间隔。                                                                |
| `alluxio.job.retention.time`                           | `7d`             | 作业历史记录保存时间。                                                                            |
| `alluxio.worker.load.file.partition.size`              | `256MiB`         | 用于在加载过程中分割大型文件的分片大小。较小的分片可以提高并发性，但可能会增加开销。                                             |
| `alluxio.worker.network.grpc.reader.threads.max`       | `2048`           | 用于并行 UFS 数据加载的 worker 线程池中的最大线程数。                                                      |

### 监控

要查看所有已注册 worker 及其当前状态（在线或离线），以及 Coordinator 列表：

```bash
$ bin/alluxio info nodes
```

## 6. 指标

监控 Coordinator 与 etcd 的交互对于确保集群健康至关重要。

> **注意：** 这些指标是内部调度器操作的低级指标。关于集群的一般健康状况和作业进度，请参考默认的 Grafana 仪表板。

| 指标                                  | 描述                                              |
| ----------------------------------- | ----------------------------------------------- |
| `alluxio_scheduler_etcd_poll`       | etcd 轮询操作的计数器。                                  |
| `alluxio_scheduler_etcd_claim`      | 从队列中成功认领的作业计数器。                                 |
| `alluxio_scheduler_etcd_reclaim`    | 从失败的 Coordinator 中回收/恢复的作业计数器。                  |
| `alluxio_scheduler_etcd_latency_ms` | 调度器执行的 etcd 操作的延迟分布。                            |
| `alluxio_scheduler_job_access_etcd` | 对 etcd 的各种作业相关访问类型（list, get, transaction）的计数器。 |
