# 虚拟路径映射

Alluxio's# 虚拟路径映射

Alluxio的虚拟路径映射功能允许您将请求从一个路径动态重定向到另一个路径。当用户或应用程序尝试访问“源”路径时，Alluxio会透明地在不同的“目标”路径上执行操作。

此功能目前适用于 **Alluxio POSIX API (FUSE)**、**Alluxio S3 API** 和 **Alluxio CLI**。

## 工作原理

虚拟路径映射使用正则表达式来定义映射规则。每个规则包括：

* **源 (`src`)**: 与客户端请求的原始路径匹配的正则表达式。
* **目标 (`dst`)**: 将操作重定向到的新路径的模板。

当请求路径时，Alluxio会根据映射规则列表进行检查。第一个匹配的规则将被应用，并且操作将被转发到目标路径。如果没有规则匹配，则使用原始路径。

## 启用虚拟路径映射

配置过程分为两步：全局启用该功能，然后定义具体的映射规则。

### 步骤1：启用功能

在您的`alluxio-site.properties`文件（或通过Helm图表值）中，添加以下设置：

```properties
alluxio.user.virtual.path.mapping.enabled=true
```

### 步骤2：定义映射规则

映射规则通过AlluxioCoordinator的REST API动态配置。您发送一个包含规则的`PUT`请求作为JSON对象。

**`curl`命令示例：**

```bash
curl -sS 'http://<coordinator-host>:19999/api/v1/conf' -X PUT -H 'Content-Type: application/json' --data '{"key":"VirtualPathMappingEntity","conf":"{\"mappingRules\":{\"rules\":[{\"src\":\"^/test/a/(.*)$\",\"dst\":\"/test/b/{{ var1 }}\"}],\"virtualDirectories\":[\"/test/a\"]}}'}'
```

`--data`负载包含一个JSON对象，其中`conf`值是定义规则的转义JSON字符串。

## 理解规则

`conf`值是定义映射规则的转义JSON字符串。为清楚起见，以下是一个未转义的示例，将`/a/b/c/`下的任何路径映射到`/x/y/z/`下的新位置：

```json
{
  "mappingRules": {
    "rules": [
      {
        "src": "^/a/b/c/(.*)$",
        "dst": "/x/y/z/{{ var1 }}"
      }
    ],
    "virtualDirectories": []
  }
}
```

* **`src`**: 正则表达式`^/a/b/c/(.*)$`匹配传入路径。`(.*)`是一个**捕获组**，用于保存`/a/b/c/`之后的任何字符。
* **`dst`**: `{{ var1 }}`占位符将第一个捕获组的值插入到目标路径中。

因此，对`/a/b/c/file.txt`的请求被透明地重定向到`/x/y/z/file.txt`。

### 复杂示例

您可以定义多个规则，这些规则从上到下进行评估。第一个匹配的规则将被使用。

此示例根据`/foo/bar/`后的第一个字符映射路径：

```json
{
  "mappingRules": {
    "rules": [
      {
        "src": "^/foo/bar/([a-b].*)$",
        "dst": "/foo1/bar1/A/{{ var1 }}"
      },
      {
        "src": "^/foo/bar/([e-g].*)$",
        "dst": "/foo1/bar1/B/{{ var1 }}"
      },
      {
        "src": "^/foo/bar/([\d].*)$",
        "dst": "/foo1/bar1/C/{{ var1 }}"
      }
    ],
    "virtualDirectories": []
  }
}
```

\*\*注意：\*\*在JSON字符串中，反斜杠`\d`必须转义（`\d`）。

### 验证您的规则

在部署规则之前，强烈建议使用提供的命令行工具进行测试。

```bash
$ bin/alluxio fs pathmapping /foo/bar/a.txt

-----------------------------------------------------------------
Input:  /foo/bar/a.txt
Output: /foo1/bar1/A/a.txt
Virtual Directory: false
-----------------------------------------------------------------
```

`Output`字段显示应用映射后的结果路径。

## 使用虚拟目录处理父路径

使用FUSE进行路径映射时的一个常见问题是，FUSE在访问文件之前会检查其父目录是否存在。如果\_原始\_父路径不存在，即使\_目标\_路径有效，FUSE也会返回错误。

例如，使用规则`^/a/b/(.*)$` -> `/x/y/{{ var1 }}`，如果目录`/a/b`在Alluxio中实际不存在，通过FUSE访问`/a/b/file.txt`将会失败。

要解决此问题，您可以定义**虚拟目录**。这些是Alluxio将始终视为存在目录的路径，从而防止FUSE引发错误。

```json
{
  "mappingRules": {
    "rules": [
      {
        "src": "^/a/b/(.*)$",
        "dst": "/x/y/{{ var1 }}"
      }
    ],
    "virtualDirectories": [
      "/a",
      "/a/b"
    ]
  }
}
```

您可以使用验证工具检查路径是否被视为虚拟目录：

```bash
$ bin/alluxio fs pathmapping /a
-----------------------------------------------------------------
Input:  /a
Output: null
Virtual Directory: true
-----------------------------------------------------------------
```

## 限制

* **性能**: 使用大量复杂的正则表达式规则可能会影响性能，因为每个路径请求都需要根据它们进行评估。
* **列出目录 (`ls`)**: 当您列出父目录（例如，`ls /foo/bar`）时，输出将**不会**显示映射的目标目录（例如，`/foo1/bar1/A`，`/foo1/bar1/B`）。但是，您仍然可以直接访问其中的文件。
