# 多可用区

## 概述

Alluxio 通过支持跨多个可用区 (AZ) 的部署来增强高可用性。如果整个可用区变得不可用，Alluxio 客户端可以自动故障转移到另一个可用区的健康集群，确保不间断的服务和数据访问。此功能与文件复制和 UFS 回退相结合，为任务关键型工作负载提供了强大的 I/O 弹性。

## 工作原理

当 Alluxio 客户端需要读取数据时，它会优先考虑其本地可用区中的 worker 以最小化延迟。如果所有本地 worker 都不可用（例如，由于区域范围的中断），客户端会自动将其请求重定向到不同可用区中的 worker。此故障转移对应用程序是无缝的。

对于跨多个可用区复制的文件，客户端将智能地选择最佳数据源，优先选择完全缓存的副本以优化性能。如果任何区域中都没有可用的 Alluxio worker，客户端将作为最后一步回退到从 UFS 读取。

## 在 Kubernetes 上启用多可用区

Alluxio Operator 使用 `ClusterGroup` 自定义资源简化了在 Kubernetes 中部署多个集群。这使您能够使用一致的配置管理多个 Alluxio 集群。有关安装 operator 的说明，请参阅 [Alluxio Operator 安装指南](https://documentation.alluxio.io/ee-ai-cn/high-availability/pages/9bxv6yM8Fd3fkHo8BnW1#id-3.-bu-shu-operator)。

在 Kubernetes 上部署多可用区设置涉及以下步骤：

### 步骤 1：准备命名空间

本指南假设您正在两个命名空间（`alx-ns`、`alx-ns-2`）中部署三个集群（`alluxio-a`、`alluxio-b`、`alluxio-c`）。首先，如果命名空间不存在，请创建它们：

```shell
kubectl create namespace alx-ns
kubectl create namespace alx-ns-2
```

### 步骤 2：定义和部署 `ClusterGroup`

创建一个 `ClusterGroup` 清单文件。此 YAML 文件定义了 Alluxio 集群，并包含启用多可用区模式的必要属性。

> **注意：** 使用 `ClusterGroup` 创建的集群共享相同的属性和资源分配模板。为确保集群部署到不同的可用区，请使用 `nodeSelector` 字段将每个集群分配到一组不同的节点。

#### Kubernetes 部署模式

协调集群的 ETCD 服务有三种支持的部署模式。

**模式 1：每个集群独立 ETCD**

每个 Alluxio 集群都使用其自己专用的 ETCD 实例运行。此模式提供了最高的隔离性。

**1. 定义拓扑：** 创建一个 `multi-az-clusters.json` 文件，其中包含每个集群的唯一 ETCD 端点。服务名称应遵循 `<cluster-name>-etcd.<namespace>` 的模式。

```json
[
   {
      "clusterNames": ["alx-ns-alluxio-a"],
      "endpoints": ["http://alluxio-a-etcd.alx-ns:2379"]
   },
   {
      "clusterNames": ["alx-ns-alluxio-b"],
      "endpoints": ["http://alluxio-b-etcd.alx-ns:2379"]
   },
   {
      "clusterNames": ["alx-ns-2-alluxio-c"],
      "endpoints": ["http://alluxio-c-etcd.alx-ns-2:2379"]
   }
]
```

**2. 创建 ConfigMap：** 将文件打包到每个命名空间中名为 `multi-cluster` 的 ConfigMap 中。

```shell
kubectl create configmap multi-cluster --from-file=multi-az-clusters.json -n alx-ns
kubectl create configmap multi-cluster --from-file=multi-az-clusters.json -n alx-ns-2
```

**3. 定义 `ClusterGroup`：** 在 `ClusterGroup` 清单中，**不要**在 `dependencies` 部分包含 `etcd`。每个集群定义将自动配置其自己的 ETCD 实例。 要点如下：

1. 必须在每个集群的properties中指定多集群 JSON 配置文件的路径。
2. ConfigMap 必须挂载到所有 Alluxio 集群组件中的 /multi-az 目录下。

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: ClusterGroup
metadata:
  name: alluxio-cluster-group
  namespace: alx-ns
spec:
  dependencies:
    dashboard:
      image: alluxio/alluxio-dashboard
      imageTag: AI-3.9-16.0.0
    license: "licenseString"
    gateway:
      image: alluxio/alluxio-gateway
      imageTag: AI-3.9-16.0.0

  groups:
    - name: alluxio-a
      namespace: alx-ns
      nodeSelector:
        region: az-1
    - name: alluxio-b
      namespace: alx-ns
      nodeSelector:
        region: az-2
    - name: alluxio-c
      namespace: alx-ns-2
      nodeSelector:
        region: az-3

  template:
    spec:
      image: alluxio/alluxio-enterprise
      imageTag: AI-3.9-16.0.0
      properties:
        alluxio.multi.cluster.enabled: "true"
        alluxio.multi.cluster.config.path: "/multi-az/multi-az-clusters.json"
      worker:
        count: 2
      configMaps:
        coordinator:
          multi-cluster: /multi-az
        worker:
          multi-cluster: /multi-az
        fuse:
          multi-cluster: /multi-az
      etcd:
        replicaCount: 1
```

应用此清单后，您可以验证每个集群在其各自的命名空间中都有自己的 `etcd` pod。

**模式 2：由 Operator 管理的共享 ETCD**

所有 Alluxio 集群共享一个由 `ClusterGroup` 部署和管理的 ETCD 集群。

**1. 定义拓扑：** 创建一个 `multi-az-clusters.json` 文件，其中所有集群都指向同一个共享 ETCD 服务。服务名称遵循 `<cluster-group-name>-etcd.<namespace>` 的模式。

```json
[
    {
        "clusterNames": ["alx-ns-alluxio-a"],
        "endpoints": ["http://alluxio-cg-etcd.default:2379"]
    },
    {
        "clusterNames": ["alx-ns-alluxio-b"],
        "endpoints": ["http://alluxio-cg-etcd.default:2379"]
    },
    {
        "clusterNames": ["alx-ns-2-alluxio-c"],
        "endpoints": ["http://alluxio-cg-etcd.default:2379"]
    }
]
```

**2. 创建 ConfigMap：** 在每个命名空间中创建 `multi-cluster` ConfigMap。

```shell
kubectl create configmap multi-cluster --from-file=multi-az-clusters.json -n alx-ns
kubectl create configmap multi-cluster --from-file=multi-az-clusters.json -n alx-ns-2
```

**3. 定义 `ClusterGroup`：** 在 `ClusterGroup` 清单中，在 `dependencies` 部分包含 `etcd`。这会指示 operator 部署一个共享的 ETCD 集群。 要点如下：

1. 必须在每个集群的properties中指定多集群 JSON 配置文件的路径。
2. ConfigMap 必须挂载到所有 Alluxio 集群组件中的 /multi-az 目录下。

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: ClusterGroup
metadata:
   name: alluxio-cg
   namespace: default
spec:
   dependencies:
      etcd:
         replicaCount: 3
      dashboard:
         image: alluxio/alluxio-dashboard
         imageTag: AI-3.9-16.0.0
      license: "licenseString"
      gateway:
         image: alluxio/alluxio-gateway
         imageTag: AI-3.9-16.0.0
   groups:
      - name: alluxio-a
        namespace: alx-ns
        nodeSelector:
           region: az-1
      - name: alluxio-b
        namespace: alx-ns
        nodeSelector:
           region: az-2
      - name: alluxio-c
        namespace: alx-ns-2
        nodeSelector:
           region: az-3
   template:
      spec:
         image: alluxio/alluxio-enterprise
         imageTag: AI-3.9-16.0.0
         properties:
           alluxio.multi.cluster.enabled: "true"
           alluxio.multi.cluster.config.path: "/multi-az/multi-az-clusters.json"
         worker:
           count: 2
         configMaps:
            coordinator:
               multi-cluster: /multi-az
            worker:
               multi-cluster: /multi-az
            fuse:
               multi-cluster: /multi-az
```

应用后，将在 `ClusterGroup` 的命名空间（本例中为 `default`）中创建一个 ETCD 集群，所有 Alluxio 集群都将连接到该集群。

**模式 3：外部 ETCD**

所有 Alluxio 集群都连接到一个预先存在的、外部管理的 ETCD 集群。这在已有中央 ETCD 的环境中很常见。

**1. 定义拓扑：** 创建一个 `multi-az-clusters.json` 文件，其中所有集群都指向外部 ETCD 端点。

```json
[
   {
      "clusterNames": ["alx-ns-alluxio-a"],
      "endpoints": ["http://external-etcd.default:2379"]
   },
   {
      "clusterNames": ["alx-ns-alluxio-b"],
      "endpoints": ["http://external-etcd.default:2379"]
   },
   {
      "clusterNames": ["alx-ns-2-alluxio-c"],
      "endpoints": ["http://external-etcd.default:2379"]
   }
]
```

**2. 创建 ConfigMap：** 在每个命名空间中创建 `multi-cluster` ConfigMap。

```shell
kubectl create configmap multi-cluster --from-file=multi-az-clusters.json -n alx-ns
kubectl create configmap multi-cluster --from-file=multi-az-clusters.json -n alx-ns-2
```

**3. 定义 `ClusterGroup`：** 在 `ClusterGroup` 清单中，禁用 operator 的 ETCD 部署，并将 Alluxio 指向外部服务。

* 从 `dependencies` 部分省略 `etcd`。
* 在 `template.spec` 中设置 `etcd.enabled: false`。
* 将 `alluxio.etcd.endpoints` 属性添加到 `template.spec.properties`。
* 必须在每个集群的properties中指定多集群 JSON 配置文件的路径。
* ConfigMap 必须挂载到所有 Alluxio 集群组件中的 /multi-az 目录下。

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: ClusterGroup
metadata:
   name: alluxio-cg
   namespace: default
spec:
   dependencies:  # 此处不包括 ETCD
      dashboard:
         image: alluxio/alluxio-dashboard
         imageTag: AI-3.9-16.0.0
      license: "licenseString"
      gateway:
         image: alluxio/alluxio-gateway
         imageTag: AI-3.9-16.0.0

   groups:
      - name: alluxio-a
        namespace: alx-ns
        nodeSelector:
           region: az-1
      - name: alluxio-b
        namespace: alx-ns
        nodeSelector:
           region: az-2
      - name: alluxio-c
        namespace: alx-ns-2
        nodeSelector:
           region: az-3

   template:
      spec:
         image: alluxio/alluxio-enterprise
         imageTag: AI-3.9-16.0.0
         properties:
           alluxio.multi.cluster.enabled: "true"
           alluxio.multi.cluster.config.path: "/multi-az/multi-az-clusters.json"
           alluxio.etcd.endpoints: "http://external-etcd.default:2379"
         worker:
           count: 2
         configMaps:
            coordinator:
               multi-cluster: /multi-az
            worker:
               multi-cluster: /multi-az
            fuse:
               multi-cluster: /multi-az
         etcd:
           enabled: false  # 显式禁用内部 ETCD
```

应用后，Alluxio 集群将启动并连接到指定的外部 ETCD 服务。

### 步骤 3：验证部署

您可以从任何 coordinator pod 运行 `info nodes` 命令来验证集群是否已连接：

```console
$ kubectl exec -it -n <namespace> <coordinator-pod-name> -- alluxio info nodes
```

成功的配置将列出所有参与集群的 worker 节点。

## 在多可用区中优化 I/O

### 优化复制文件的 I/O

Alluxio 支持优化[多副本文件](/ee-ai-cn/high-availability/multiple-replicas.md)的 I/O。对于跨可用区复制的文件，客户端会智能地选择最佳数据源。客户端将按照以下顺序选择首选数据源：

1. 完全缓存了文件的本地 worker。
2. 完全缓存了文件的远程 worker。
3. 本地 worker（如果没有完全缓存的副本）。
4. 远程 worker（如果没有可用的本地 worker）。
5. UFS（作为最后手段）。

此逻辑确保客户端优先选择最快、最完整的数据副本，即使跨区域也是如此。

### 被动缓存

在多可用区部署中，建议启用被动缓存。当客户端从远程集群读取文件时，被动缓存会自动在客户端的本地集群中创建该文件的副本，详见[被动创建副本](https://documentation.alluxio.io/ee-ai-cn/high-availability/pages/xtOhRpdirRIHGpedrU1W#被动创建副本)。这确保了对同一文件的后续读取可以在本地提供，从而提高性能和数据局部性。

要启用优化的 I/O 和被动缓存，请将以下属性添加到 `alluxio-site.properties`：

```properties
# Note that multi-replica optimized IO must be enabled for passive cache to take effect
alluxio.user.replica.prefer.cached.replicas=true
alluxio.user.file.passive.cache.enabled=true
```


---

# 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/high-availability/multi-az.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.
