> For the complete documentation index, see [llms.txt](https://documentation.alluxio.io/ee-ai-cn/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://documentation.alluxio.io/ee-ai-cn/administration/managing-ring.md).

# 哈希环与 Worker 生命周期

本指南涵盖一致性哈希环的配置、Worker 生命周期操作和诊断流程。关于单个 Worker 的配置（存储、资源、JVM、网络），请参阅 [Worker 配置](/ee-ai-cn/administration/managing-worker.md)。关于集群级别的操作（扩展、升级、Coordinator），请参阅 [集群管理](/ee-ai-cn/administration/managing-alluxio.md)。

{% hint style="warning" %}
哈希环设置应在初始集群设置期间定义。在正在运行的集群上修改这些配置是一项破坏性操作，将导致所有缓存数据丢失，因为它会更改数据到 Worker 的映射方式。
{% endhint %}

Alluxio 使用一致性哈希环以去中心化的方式将数据映射到 Worker。您可以微调其行为，以针对不同的集群环境和工作负载进行优化。

## 1. 部署前配置

在首次部署前设置以下属性：

| 属性                                                                                   | 默认值        | 何时调整                                                                                             |
| ------------------------------------------------------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------ |
| `alluxio.user.dynamic.consistent.hash.ring.enabled`                                  | `true`（动态） | 仅当需要在 Worker 短暂不可用时保持稳定的环视图，才设置为 `false`（静态）——参见[配置哈希环模式](#pei-zhi-ha-xi-huan-mo-shi)            |
| `alluxio.user.worker.selection.policy.consistent.hash.virtual.node.count.per.worker` | `2000`     | 极少调整——仅适用于非常小或严重不均衡的集群。参见[调整虚拟节点以实现负载均衡](#tiao-zheng-xu-ni-jie-dian-yi-shi-xian-fu-zai-jun-heng) |
| `alluxio.user.worker.selection.policy.consistent.hash.provider.impl`                 | `DEFAULT`  | 异构 Worker 集群设置为 `CAPACITY`。参见[针对异构 Worker 进行优化](#zhen-dui-yi-gou-worker-jin-xing-you-hua)        |

{% tabs %}
{% tab title="Kubernetes (Operator)" %}
在 `alluxio-cluster.yaml` 的 `.spec.properties` 下设置：

```yaml
spec:
  properties:
    alluxio.user.dynamic.consistent.hash.ring.enabled: "true"
    alluxio.user.worker.selection.policy.consistent.hash.provider.impl: DEFAULT
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}
在 `conf/alluxio-site.properties` 中设置（对 client、worker、coordinator 进程都生效）：

```properties
alluxio.user.dynamic.consistent.hash.ring.enabled=true
alluxio.user.worker.selection.policy.consistent.hash.provider.impl=DEFAULT
```

{% endtab %}
{% endtabs %}

## 2. 哈希环配置

### 配置哈希环模式

一致性哈希环可以以两种模式运行：动态（默认）或静态。

在**动态模式**（默认）下，哈希环仅包含在线的 Worker。当 Worker 下线并超过存活检测超时后，它会从环中移除，其虚拟节点被重新分配给在线 Worker。这是大多数部署的最佳选择——环能自动适应永久性拓扑变更（如扩缩容或节点替换）。

在**静态模式**下，哈希环保留所有已注册的 Worker，无论其在线状态如何。此模式专为**计划性短期维护**场景设计——滚动软件升级、硬件维护或短暂重启等 Worker 预期会很快重新加入的情况。通过将离线 Worker 保留在环中，Alluxio 避免了缓存数据的重新分片：当 Worker 恢复时，它收回原始环槽位，所有缓存数据立即可路由。代价是在停机窗口期间，哈希到离线 Worker 的请求会 fallback 到 UFS。

要配置模式，请设置 `alluxio.user.dynamic.consistent.hash.ring.enabled` 属性。将其设置为 `true` 表示动态模式（默认值），设置为 `false` 表示静态模式。

### 调整虚拟节点以实现负载均衡

为确保数据和 I/O 请求的均匀分布，Alluxio 使用虚拟节点。每个 Worker 都映射到哈希环上的多个虚拟节点，这有助于在集群中更有效地平衡负载。

您可以通过配置 `alluxio.user.worker.selection.policy.consistent.hash.virtual.node.count.per.worker` 属性（默认值：`2000`）来调整每个 Worker 的虚拟节点数。调整此值有助于微调负载分布，尤其是在具有不同工作负载或少量 Worker 的集群中。

### 针对异构 Worker 进行优化

默认情况下，一致性哈希算法假定所有 Worker 都具有相同的容量。在具有异构 Worker（例如，不同的存储容量或网络速度）的集群中，您可以启用基于容量的分配，以实现更均衡的资源利用。这确保了具有更多存储空间的 Worker 能处理相应更大部分的数据。

要启用此功能，请将 `alluxio.user.worker.selection.policy.consistent.hash.provider.impl` 属性设置为 `CAPACITY`。默认值为 `DEFAULT`，它为每个 Worker 分配相同数量的虚拟节点。

关于 Worker 侧的 YAML 配置（节点标记、`workerGroups`），请参阅 [异构 Worker](/ee-ai-cn/administration/managing-worker.md#yi-gou-worker)。

### Worker 存活检测

每个 Worker 主动与 etcd 保持通信以维持其活跃状态。若 Worker 在超时时间内未能与 etcd 通信，则被视为离线：

```properties
# 网络抖动后 worker 重连较慢时可适当增大（默认值：15s）
alluxio.worker.failure.detection.timeout=30s
```

在动态模式下，`OFFLINE` 的 Worker 在超时后从哈希环中移除，其虚拟节点被重新分配给在线 Worker。在静态模式下，`OFFLINE` 条目仍留在环中——哈希到该节点的请求会 fallback 到 UFS，直到 Worker 重新加入或被显式移除。

### 客户端 Worker 列表刷新

客户端维护 Worker 列表的本地快照，并定期从 etcd 刷新：

```properties
# 降低可加快故障切换；增大可减少 etcd 读压力（默认值：45s）
alluxio.user.worker.list.refresh.interval=2m
```

添加或移除 Worker 后，客户端将在一个刷新周期内反映变更。如需在故障恢复时立即生效，可重启客户端进程或临时缩短此间隔。

## 3. Worker 在环上的生命周期

Alluxio 的去中心化架构依赖于通过一致性哈希环管理的 Worker。本节介绍 Worker 加入、离开和重启环的操作流程。

### 检查 Worker 状态

查看所有已注册 Worker 及其当前状态：

{% tabs %}
{% tab title="Kubernetes (Operator)" %}

```shell
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- alluxio info nodes
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}

```shell
bin/alluxio info nodes
```

{% endtab %}
{% endtabs %}

```console
WorkerID                              Host               Status
e87b4097-b7f8-48a4-a388-3197124ebbe7  ip-172-16-10-12    ONLINE
a1f23c45-d678-90ab-cdef-123456789012  ip-172-16-10-13    ONLINE
```

#### 诊断 OFFLINE 条目导致的哈希环膨胀

健康集群的 `alluxio info nodes` 输出中，ONLINE 条目数应等于配置的 Worker 数。若总条目数超出预期，或 ONLINE 数低于 Worker 数，说明 etcd 中存在过期 `OFFLINE` 条目。

**影响（静态模式）：** 在静态模式（`alluxio.user.dynamic.consistent.hash.ring.enabled=false`）下，`OFFLINE` 条目在环中无限期保留。过期条目占比越高，fallback 到 UFS 的哈希查找比例越大——将缓存命中变为直接读 S3/GCS 的速度。

在动态模式（默认）下，`OFFLINE` 条目在 `alluxio.worker.failure.detection.timeout` 后自动从环中移除（参见 [Worker 存活检测](#worker-cun-huo-jian-ce)），不会持续膨胀。但每次以新 UUID 重启仍会重新分配虚拟节点，导致已缓存数据暂时不可访问。

验证哈希环健康——ONLINE 数量应等于配置的 Worker 数：

{% tabs %}
{% tab title="Kubernetes (Operator)" %}

```shell
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- alluxio info nodes | grep -c ONLINE
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}

```shell
bin/alluxio info nodes | grep -c ONLINE
```

{% endtab %}
{% endtabs %}

如需从 etcd 中删除某个过期的 `OFFLINE` 条目，从 `alluxio info nodes` 输出中获取其 UUID，然后执行 `alluxio process remove-worker`：

{% tabs %}
{% tab title="Kubernetes (Operator)" %}

```shell
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- \
  alluxio process remove-worker -n <STALE_WORKER_UUID>
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}

```shell
bin/alluxio process remove-worker -n <STALE_WORKER_UUID>
```

{% endtab %}
{% endtabs %}

### 添加或移除 Worker

新 Worker 在启动时会自动在 etcd 中注册并加入哈希环。移除 Worker 后，其哈希环部分将被重新分配给剩余 Worker，在数据从 UFS 重新加载期间会出现缓存未命中率暂时增加。

{% tabs %}
{% tab title="Kubernetes (Operator)" %}
调整 `alluxio-cluster.yaml` 中的 `worker.count` 并应用——完整步骤参见 [扩展集群](/ee-ai-cn/administration/managing-alluxio.md#kuo-zhan-ji-qun)。
{% endtab %}

{% tab title="Docker / Bare-Metal" %}
在目标主机上启动新的 Worker 进程（Docker：`docker run ... alluxio/alluxio-enterprise worker`；裸机：`bin/alluxio process start worker`）。要移除，则停止该 Worker 进程；注销步骤参见[永久移除 Worker](#yong-jiu-yi-chu-worker)。
{% endtab %}
{% endtabs %}

### 永久移除 Worker

下线某个节点时，需先停止 Worker，再从 etcd 中显式注销该 Worker，避免其以过期 `OFFLINE` 条目的形式残留。

**步骤 1：停止 Worker。**

{% tabs %}
{% tab title="Kubernetes (Operator)" %}
在 `alluxio-cluster.yaml` 中缩减 `worker.count` 并应用：

```shell
kubectl apply -f alluxio-cluster.yaml
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}
停止下线主机上的 Worker 进程（Docker：`docker stop alluxio-worker`；裸机：`bin/alluxio process stop worker`）。
{% endtab %}
{% endtabs %}

**步骤 2：从 etcd 注销 Worker。** 通过 `alluxio info nodes` 获取该 Worker 的 UUID，然后执行 `alluxio process remove-worker`：

{% tabs %}
{% tab title="Kubernetes (Operator)" %}

```shell
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- alluxio info nodes
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- \
  alluxio process remove-worker -n <WORKER_UUID>
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}

```shell
bin/alluxio info nodes
bin/alluxio process remove-worker -n <WORKER_UUID>
```

{% endtab %}
{% endtabs %}

在动态模式下，跳过步骤 2 通常是安全的——`OFFLINE` 条目会在 `alluxio.worker.failure.detection.timeout` 超时后自动清除。在静态模式下，步骤 2 是必须执行的，否则过期条目将无限期留在哈希环中。

### 重启 Worker

Worker 重启时会暂时被标记为离线。配置身份持久化后，Worker 将以相同 UUID 重新加入——保留其环位置、缓存数据和负载分布。

未配置身份持久化时，每次重启会生成新的 UUID 和不同的环槽位，导致缓存未命中和潜在的环膨胀。详情请参阅 [配置哈希环模式](#pei-zhi-ha-xi-huan-mo-shi) 和 [诊断 OFFLINE 条目导致的哈希环膨胀](#zhen-duan-offline-tiao-mu-dao-zhi-de-ha-xi-huan-peng-zhang)。

#### 持久化 Worker 身份

{% tabs %}
{% tab title="Kubernetes (Operator)" %}
在首次部署前，在 `alluxio-cluster.yaml` 中设置 `worker.systemInfo.hostPath`：

```yaml
spec:
  worker:
    useExternalId: false
    systemInfo:
      hostPath: /mnt/alluxio/system-info
```

{% endtab %}

{% tab title="Docker" %}
在首次启动前，在宿主机上预先创建空文件并挂载为 volume。Alluxio 启动时会将 UUID 写入该文件，容器重建后文件依然保留：

```shell
sudo mkdir -p /etc/alluxio
sudo touch /etc/alluxio/worker_identity
```

在 worker `docker run` 命令中添加：

```shell
-v /etc/alluxio/worker_identity:/opt/alluxio/conf/worker_identity
```

{% hint style="warning" %}
使用 `-v` 挂载前，**必须**先在宿主机上创建该文件。若宿主机路径不存在，Docker 会在该路径创建一个**目录**而非文件，导致 Alluxio 启动失败并报错 `IOException: Is a directory`。
{% endhint %}

完整 Docker 配置指南参见 [附录 B：Worker 节点身份](https://documentation.alluxio.io/ee-ai-cn/administration/pages/Wb9Sk0fPVxU8wn1ZLnEK#b.-worker-节点身份)。
{% endtab %}

{% tab title="裸机" %}
将 `alluxio.worker.identity.uuid.file.path` 设置为重启后仍然存在的路径：

```properties
alluxio.worker.identity.uuid.file.path=/etc/alluxio/worker_identity
```

该文件在首次启动时自动创建。若需手动固定现有 Worker 的 UUID（如迁移到持久路径时），先从 `alluxio info nodes` 获取当前 UUID，再写入配置的路径。
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
如果 Worker 被迁移到不同的主机，请在启动 Worker 之前将身份文件复制到新主机的相同路径。若文件缺失，Worker 将以新 UUID 注册，之前身份下的所有缓存数据将不可访问。
{% endhint %}

### Worker 重启后的缓存恢复

**已配置身份持久化的情况下**，重启的 Worker 以相同 UUID 重新加入哈希环，其此前缓存的数据页仍可访问。但是，恢复的 Worker 可能缺少**在其离线期间被加载到其他 Worker 上的数据**——停机期间，这些文件被路由到临时持有该 Worker 哈希环槽位的其他 Worker，因此恢复的 Worker 从未缓存过它们。一旦重新加入哈希环，这些文件重新映射到此 Worker，但其本地缓存中并没有这些数据。

使用以下步骤填补空洞，同时避免重复加载：

{% tabs %}
{% tab title="Kubernetes (Operator)" %}

```shell
# 确认 Worker 已重新加入哈希环
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- \
  alluxio info nodes | grep ONLINE
# 预期：N 条记录全部显示 ONLINE（N = 配置的 Worker 数量）

# 重新触发加载——跳过任意 Worker 上已缓存的文件
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- \
  alluxio job load --path <ufs-or-alluxio-path> --submit --skip-if-exists

# 监控直到 SUCCEEDED
kubectl exec -n <NAMESPACE> alluxio-cluster-coordinator-0 -- \
  alluxio job load --path <ufs-or-alluxio-path> --progress
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}

```shell
# 确认 Worker 已重新加入哈希环
bin/alluxio info nodes | grep ONLINE
# 预期：N 条记录全部显示 ONLINE（N = 配置的 Worker 数量）

# 重新触发加载
bin/alluxio job load --path <ufs-or-alluxio-path> --submit --skip-if-exists

# 监控直到 SUCCEEDED
bin/alluxio job load --path <ufs-or-alluxio-path> --progress
```

{% endtab %}
{% endtabs %}

`--skip-if-exists` 确保已在健康 Worker 上缓存的文件不会从 UFS 重复拉取。只有当前映射到恢复 Worker 但该 Worker 尚未缓存的文件才会被加载。

**未配置身份持久化的情况下**，Worker 以新 UUID 注册，占据不同的哈希环槽位。旧 UUID 下缓存的所有数据变为不可访问，需要完整重新加载才能恢复缓存覆盖率。这正是身份持久化作为生产环境必备配置的原因——参阅 [持久化 Worker 身份](#chi-jiu-hua-worker-shen-fen)。
