# Worker 配置

本指南涵盖 Alluxio 单个 Worker 的配置：存储后端、容量规划、资源限制、JVM 调优和网络绑定。关于哈希环相关的 Worker 操作（添加、移除、重启、身份持久化），请参阅 [哈希环与 Worker 生命周期](/ee-ai-cn/administration/managing-ring.md)。关于集群级别的操作（扩展、升级、Coordinator、UFS、多租户），请参阅 [集群管理](/ee-ai-cn/administration/managing-alluxio.md)。

## 1. Worker 存储

每个 Worker 将缓存数据保存在本地的 [page store](https://documentation.alluxio.io/ee-ai-cn/administration/pages/uw7Vlrzw6022oCfnpoka#id-5.-worker-cun-chu-page-store) 中。本节介绍存储后端选型、容量规划和磁盘布局。

### 配置 Page Store 位置

{% tabs %}
{% tab title="Kubernetes (Operator)" %}
Operator 支持两种 page store 后端。

**默认（hostPath）：** Worker 将缓存写入节点文件系统的 `/mnt/alluxio/pagestore`。

```yaml
spec:
  worker:
    pagestore:
      # 默认 hostPath: /mnt/alluxio/pagestore，指向节点的本地文件系统
      size: 100Gi
      reservedSize: 10Gi
```

**PVC 方式：** 若需 Worker 缓存跨 pod 重启或重调度后仍然保留，为 page store 指定一个 PersistentVolumeClaim (PVC)。

```yaml
spec:
  worker:
    pagestore:
      type: persistentVolumeClaim
      storageClass: ""    # 默认为 "standard"；空字符串表示静态绑定
      size: 100Gi
      reservedSize: 10Gi
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}
通过 Alluxio 属性设置 page store 目录和大小。Docker 部署通过 `ALLUXIO_JAVA_OPTS` 传入，并把宿主机目录作为 volume 挂载，使缓存在容器重建后仍然保留：

```shell
docker run ... \
  -v /data/alluxio-cache:/data/alluxio-cache \
  -e ALLUXIO_JAVA_OPTS=" \
    -Dalluxio.worker.page.store.dirs=/data/alluxio-cache \
    -Dalluxio.worker.page.store.sizes=<CACHE_SIZE>" \
  alluxio/alluxio-enterprise worker
```

裸机部署在 `conf/alluxio-site.properties` 里设置同样的属性：

```properties
alluxio.worker.page.store.dirs=/data/alluxio-cache
alluxio.worker.page.store.sizes=<CACHE_SIZE>
```

{% endtab %}
{% endtabs %}

### Page Store 容量规划

* `size`：单个 Worker 的缓存容量。不得超过 Worker 节点上的可用磁盘。
* `reservedSize`：为内部操作预留的空间（临时 page 写入、元数据缓存）。设为 `size` 的 10% 左右，通常 10–100 GiB。
* 确保 `size + reservedSize ≤ 可用磁盘空间`。

云厂商宣传的磁盘大小是 GB（十进制），而 Kubernetes 的 `Gi` 是二进制 GiB。标称 "1000 GB" 的 EBS 卷实际可用约 931 GiB。将 `size` 设为实际可用空间（`df -h <page-store-path>` 查看）的 \~90%，为文件系统开销和 `reservedSize` 留出余量。`size` 过大会导致 Worker 启动失败：`quota (NNN) exceeds the total disk space`。

### 多盘配置

对于有多块数据盘的节点，将 page store 配置为跨所有磁盘——这样可以将 page I/O 分摊到多块盘，提升总吞吐。使用逗号分隔的路径和大小：

```yaml
spec:
  worker:
    pagestore:
      hostPath: /mnt/disk1/alluxio/pagestore,/mnt/disk2/alluxio/pagestore
      size: 800Gi,800Gi
      reservedSize: 100Gi
```

每个目录必须对应一块独立的物理盘——多个 page store 目录位于同一块盘上不会带来收益。

另一种方式是在操作系统层用 RAID 0 将多块盘组成一个逻辑卷，然后只配置单个 `hostPath`。这种方式 Alluxio 配置更简单，但绑定了所有磁盘的生命周期——任意一块盘坏掉整个阵列都会丢失。

### 异构 Worker

本节所述的 `workerGroups` 机制仅适用于 Kubernetes Operator。在 Docker 或裸机部署中，异构 Worker 通过为每个 Worker 单独配置 `alluxio-site.properties`（指定该节点的 page store 路径和大小）实现。

当集群中的 Worker 磁盘规格不同（例如一组有单块 1 TB 盘，另一组有两块 800 GB 盘），使用 `workerGroups` 为每组定义不同的配置。

**步骤 1：分组并标记节点：**

```shell
# 标记单盘节点
kubectl label nodes <node-name> apps.alluxio.com/disks=1
# 标记双盘节点
kubectl label nodes <node-name> apps.alluxio.com/disks=2
```

**步骤 2：定义 worker groups 并启用容量感知哈希环。**

对于异构集群，应同时将 `alluxio.user.worker.selection.policy.consistent.hash.provider.impl` 设置为 `CAPACITY`，这样存储容量更大的 Worker 会分到相应更大比例的数据。关于该属性的详细说明，参见 [针对异构 Worker 进行优化](/ee-ai-cn/administration/managing-ring.md#zhen-dui-yi-gou-worker-jin-xing-you-hua)。

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  properties:
    alluxio.user.worker.selection.policy.consistent.hash.provider.impl: CAPACITY

  # 所有 worker 的通用配置
  worker:
    resources:
      limits:
        memory: 40Gi
      requests:
        memory: 36Gi
    jvmOptions: ["-Xmx20g", "-Xms20g", "-XX:MaxDirectMemorySize=16g"]

  # 为每组 worker 定义独立配置
  workerGroups:
  - worker:
      count: 10
      nodeSelector:
        apps.alluxio.com/disks: 1
      pagestore:
        hostPath: /mnt/disk1/alluxio/pagestore
        size: 1Ti
        reservedSize: 100Gi
  - worker:
      count: 12
      nodeSelector:
        apps.alluxio.com/disks: 2
      pagestore:
        hostPath: /mnt/disk1/alluxio/pagestore,/mnt/disk2/alluxio/pagestore
        size: 800Gi,800Gi
        reservedSize: 100Gi
```

{% hint style="info" %}
虽然这提供了灵活性，但确保每个 worker group 内部配置一致至关重要。配置错误可能导致意料之外的错误。
{% endhint %}

## 2. 资源与 JVM 调优

{% tabs %}
{% tab title="Kubernetes (Operator)" %}
在 `alluxio-cluster.yaml` 中按组件配置资源限制和 JVM 选项：

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: AlluxioCluster
spec:
  worker:
    count: 2
    resources:
      # 生产环境 Worker 建议将 requests 设为与 limits 相同，使 Pod 进入
      # Guaranteed QoS 级别，在节点资源紧张时被驱逐的优先级最低。
      limits:
        cpu: "12"
        memory: "36Gi"
      requests:
        cpu: "12"
        memory: "36Gi"
    jvmOptions:
      - "-Xmx22g"
      - "-Xms22g"
      - "-XX:MaxDirectMemorySize=10g"
  coordinator:
    resources:
      # Coordinator 也建议进入 Guaranteed QoS 级别——将 requests 设为与 limits 相同。
      limits:
        cpu: "12"
        memory: "36Gi"
      requests:
        cpu: "12"
        memory: "36Gi"
    jvmOptions:
      - "-Xmx4g"
      - "-Xms1g"
```

{% endtab %}

{% tab title="Docker / Bare-Metal" %}
Docker 部署通过 `ALLUXIO_JAVA_OPTS` 设置 JVM 选项，通过 `--memory` 和 `--cpus` 设置容器资源上限：

```shell
docker run ... \
  --memory=36g \
  --cpus=12 \
  -e ALLUXIO_JAVA_OPTS=" \
    -Xmx22g -Xms22g -XX:MaxDirectMemorySize=10g" \
  alluxio/alluxio-enterprise worker
```

裸机部署在 `conf/alluxio-env.sh` 中设置 JVM 选项：

```shell
ALLUXIO_WORKER_JAVA_OPTS+=" -Xmx22g -Xms22g -XX:MaxDirectMemorySize=10g"
ALLUXIO_COORDINATOR_JAVA_OPTS+=" -Xmx4g -Xms1g"
```

{% endtab %}
{% endtabs %}

### 内存限制公式

```
memory limit ≥ -Xmx + -XX:MaxDirectMemorySize + 2–4 GiB (JVM 开销)
```

上面 worker 示例（`-Xmx22g`、`-XX:MaxDirectMemorySize=10g`）：最小内存为 22 + 10 + 2 = 34 GiB，示例中设为 36 GiB。

{% hint style="info" %}
若省略 `-XX:MaxDirectMemorySize`，JVM 默认将其设为与 `-Xmx` 相同的值，因此容器内存限制通常需要 2.5 倍 `-Xmx` 或更多。
{% endhint %}

### 诊断 OOM

若 Worker 被 OOM 杀死（退出码 137），使用下列命令确认原因。

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

```shell
# 查看 pod 事件
kubectl describe pod <worker-pod-name> -n alx-ns
# 查找 "OOMKilled" 或 "Exit Code: 137"

# 查看前一次容器崩溃前的日志
kubectl logs <worker-pod-name> -n alx-ns --previous | tail -50
# 查找 "OutOfMemoryError" 或 "java.lang.OutOfMemoryError"
```

{% endtab %}

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

```shell
# Docker：查看已退出容器的状态
docker inspect <container-id> --format='{{.State.OOMKilled}} {{.State.ExitCode}}'
# "true 137" 表示被 OOM 杀掉

# 查看 worker 日志中的 OutOfMemoryError
tail -100 /opt/alluxio/logs/worker.log | grep -i OutOfMemoryError
```

{% endtab %}
{% endtabs %}

| 症状                                                 | 根因                              | 修复                                       |
| -------------------------------------------------- | ------------------------------- | ---------------------------------------- |
| `Exit Code 137`，无 Java 报错                          | 容器超过内存限制——被 Linux OOM killer 杀掉 | 增大 `resources.limits.memory`             |
| `java.lang.OutOfMemoryError: Java heap space`      | `-Xmx` 偏小                       | 增大 `-Xmx` 并相应提高容器内存上限                    |
| `java.lang.OutOfMemoryError: Direct buffer memory` | `-XX:MaxDirectMemorySize` 偏小    | 增大 `-XX:MaxDirectMemorySize` 并相应提高容器内存上限 |

## 3. Worker 网络配置

### 将 Worker 绑定到指定网卡

将 Worker 绑定到指定的本地网卡（假设网卡名为 `NIC1`），需要分别为各服务设置 bind device：

```properties
alluxio.worker.rpc.bind.device=NIC1
alluxio.worker.web.bind.device=NIC1
alluxio.worker.data.bind.device=NIC1
```


---

# 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/administration/managing-worker.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.
