# HDFS

此指南描述了配置 [HDFS](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html)作为 Alluxio 的底层存储系统的说明。\
HDFS，即 Hadoop 分布式文件系统，是 Hadoop 应用程序使用的主要分布式存储系统，为 Hadoop 生态系统中的大数据处理提供可靠和可扩展的存储。\
有关 HDFS 的更多信息，请阅读其 [文档](https://hadoop.apache.org/docs/stable/hadoop-project-dist/hadoop-hdfs/HdfsUserGuide.html)

## 先决条件

为了准备使用 HDFS 与 Alluxio：

| `<HDFS_NAMENODE>`  | 处理客户端连接到集群的NameNode的IP地址。NameNode是Apache Hadoop HDFS架构中的主节点，负责维护和管理DataNode（从节点）上存在的数据块。 |
| ------------------ | ---------------------------------------------------------------------------------------- |
| `<HDFS_PORT>`      | NameNode接受客户端连接的端口号。                                                                     |
| `<HADOOP_VERSION>` | Hadoop版本                                                                                 |

## 基本设置

使用 [挂载表操作](https://documentation.alluxio.io/ee-ai-cn/ai-3.6/overview/namespace#挂载表操作)\
来增加一个新的挂载点, 指定Alluxio路径在其上创建挂载，指定HDFS的路径作为UFS URI。\
密钥和配置选项也可以通过指定 `--option` 标志作为挂载命令的一部分来指定，如[配置挂载点](https://documentation.alluxio.io/ee-ai-cn/ai-3.6/overview/namespace#对不同挂载点使用不同的配置)所述。

以下是通过 Operator 创建挂载点的 `ufs.yaml` 文件示例：

```yaml
apiVersion: k8s-operator.alluxio.com/v1
kind: UnderFileSystem
metadata:
  name: alluxio-hdfs
  namespace: alx-ns
spec:
  alluxioCluster: alluxio-cluster
  path: hdfs://<HDFS_NAMENODE>:<HDFS_PORT>
  mountPath: /hdfs
  mountOptions:
    alluxio.underfs.version: <HADOOP_VERSION>
```

不使用 Operator 的情况下, 将 `hdfs://<HDFS_NAMENODE>:<HDFS_PORT>` 挂载到 `/hdfs` 的示例命令：

```shell
bin/alluxio mount add --path /hdfs/ --ufs-uri hdfs://<HDFS_NAMENODE>:<HDFS_PORT> \
  --option alluxio.underfs.version=<HADOOP_VERSION>
```

例如，如果您在本地使用默认端口运行HDFS的NameNode，并将HDFS根目录映射到Alluxio，则底层存储地址可以是 `hdfs://localhost:8020`；\
如果只有HDFS目录 `/alluxio/data` 映射到Alluxio，则地址可以是 `hdfs://localhost:8020/alluxio/data`。

要找出HDFS正在运行的位置，请使用 `hdfs getconf -confKey fs.defaultFS` 命令获取HDFS正在监听的默认主机名和端口号。

此外，您可能需要将 `alluxio.underfs.version` 属性指定为您的HDFS版本。\
请参阅[使用特定版本挂载HDFS](#使用特定版本挂载hdfs)。

## 高级设置

### 指定HDFS配置位置

当HDFS具有非默认配置时，您需要配置Alluxio服务器以使用正确的配置文件访问HDFS。\
请注意，一旦设置了这个，使用Alluxio客户端的应用程序不需要任何特殊的配置。

有两种可行的方法：

* 从您的Hadoop安装中将 `hdfs-site.xml` 和 `core-site.xml` 复制或创建符号链接到 `${ALLUXIO_HOME}/conf`。\
  确保这在运行Alluxio的所有服务器上都设置好了。
* 或者，您可以在 `conf/alluxio-site.propertie` s中设置属性 `alluxio.underfs.hdfs.configuration` 指向您的 `hdfs-site.xml` 和 `core-site.xml`。\
  确保这个配置在运行Alluxio的所有服务器上都设置好了。

```properties
alluxio.underfs.hdfs.configuration=/path/to/hdfs/conf/core-site.xml:/path/to/hdfs/conf/hdfs-site.xml
```

### HDFS NameNode 高可用模式

要将 Alluxio 配置为与 HDFS NameNode 在高可用模式下配合工作，首先需要配置 Alluxio 服务器以[使用正确的配置文件访问 HDFS](#指定HDFS配置位置)。

此外，将底层存储地址设置为 `hdfs://nameservice/`（`nameservice` 是已在 `hdfs-site.xml` 中配置的 [HDFS nameservice](https://hadoop.apache.org/docs/r3.3.1/hadoop-project-dist/hadoop-hdfs/HDFSHighAvailabilityWithQJM.html#Configuration_details)。\
要将 HDFS 子目录挂载到 Alluxio 而不是整个 HDFS 命名空间，请将底层存储地址更改为类似 `hdfs://nameservice/alluxio/data` 的内容。

```console
$ bin/alluxio mount add --path /hdfs/ --ufs-uri hdfs://nameservice/
```

### 用户/权限 映射

为了确保在 HDFS 中文件/目录的权限信息（包括用户、组和模式）与 Alluxio 一致\
（例如，在 Alluxio 中由用户 Foo 创建的文件在持久化到 HDFS 时也会以用户 Foo 作为所有者），\
启动 Alluxio 主节点和工作节点的用户需要满足以下条件之一：

1. 是 [HDFS 超级用户](http://hadoop.apache.org/docs/r3.3.1/hadoop-project-dist/hadoop-hdfs/HdfsPermissionsGuide.html#The_Super-User)。\
   也就是说，使用启动 HDFS NameNode 进程的相同用户也启动 Alluxio coordinator进程和worker进程。
2. 是 [HDFS 超级用户组](http://hadoop.apache.org/docs/r3.3.1/hadoop-project-dist/hadoop-hdfs/HdfsPermissionsGuide.html#Configuration_Parameters)的成员。\
   编辑 HDFS 配置文件 `hdfs-site.xml`，检查配置属性 `dfs.permissions.superusergroup` 的值。\
   如果该属性设置了一个组（例如，"hdfs"），则将用于启动 Alluxio 进程的用户（例如，"alluxio"）添加到此组（"hdfs"）；\
   如果未设置此属性，则将一个组添加到此属性中，其中您正在运行 Alluxio 的用户是这个新添加的组的成员。

上述设置的用户仅是启动 Alluxio coordinator进程和worker进程的身份。\
一旦启动了 Alluxio 服务器，就不需要再使用此用户运行 Alluxio 客户端应用程序。

### 连接到安全的HDFS

如果您的 HDFS 集群启用了 Kerberos，首先配置 Alluxio 服务以[使用正确的配置文件访问 HDFS](#指定HDFS配置位置)。

此外，需要安全配置使 Alluxio 能够与 HDFS 集群通信。\
在 `alluxio-site.properties` 中设置以下 Alluxio 属性：

```properties
alluxio.security.kerberos.server.keytab.file=<YOUR_HDFS_KEYTAB_FILE_PATH>
alluxio.security.kerberos.server.principal=hdfs/<_HOST>@<REALM>
alluxio.security.kerberos.client.keytab.file=<YOUR_HDFS_KEYTAB_FILE_PATH>
alluxio.security.kerberos.client.principal=hdfs/<_HOST>@<REALM>
```

如果连接到安全的 HDFS，请在所有 Alluxio 节点上运行 kinit。\
使用之前在 `alluxio-site.properties` 中配置的 principal `hdfs` 和 keytab。\
已知的限制是，Kerberos TGT 可能在最大续订寿命后过期。\
您可以通过定期续订 TGT 来解决此问题。\
否则，在启动 Alluxio 服务时可能会看到 `No valid credentials provided (Mechanism level: Failed to find any Kerberos tgt)`。\
另一个选项是设置 `alluxio.hadoop.kerberos.keytab.login.autorenewal=true`，以便自动刷新 TGT。

用户还可以使用 `alluxio.hadoop.security.krb5.conf` 来指定 `krb5.conf` 文件位置，\
并使用 `alluxio.hadoop.security.authentication` 来指定身份验证方法。

#### 自定义 Kerberos Realm/KDC

默认情况下，Alluxio 将使用机器级别的 Kerberos 配置来确定 Kerberos realm和 KDC。\
您可以通过设置 JVM 属性 `java.security.krb5.realm` 和 `java.security.krb5.kdc` 来覆盖这些默认值。

要设置这些属性，在 `conf/alluxio-env.sh` 中设置 `ALLUXIO_JAVA_OPTS`。

```sh
ALLUXIO_JAVA_OPTS+=" -Djava.security.krb5.realm=<YOUR_KERBEROS_REALM> -Djava.security.krb5.kdc=<YOUR_KERBEROS_KDC_ADDRESS>"
```

### 使用特定版本挂载HDFS

用户可以以多种方式将指定版本的 HDFS 集群挂载为 Alluxio 命名空间的底层存储。\
在挂载具有特定版本的 HDFS 之前，请确保已构建了具有该特定版本的 HDFS 的客户端。\
您可以通过转到 Alluxio 目录下的 `lib` 目录来检查此客户端是否存在。

#### 设置Alluxio配置文件

当将 Alluxio 根目录的底层存储挂载到特定的 HDFS 版本时，可以将以下行添加到Alluxio配置文件（`conf/alluxio-site.properties`）中:

```properties
alluxio.underfs.version=3.3
```

#### 支持的HDFS版本

Alluxio 支持以下版本的 HDFS 作为挂载选项 `alluxio.underfs.version` 的有效参数：

* Apache Hadoop: 2.10, 3.3

如果所需版本不可用，请联系您的 Alluxio 客户经理（邮箱：<sales@alluxio.com>）。

### Hadoop 本地库

Hadoop 自带一个本地库，与其 Java 实现相比，该库提供了更好的性能和额外的功能。\
例如，当使用本地库时，HDFS 客户端可以使用本地校验和函数，这比默认的 Java 实现更高效。\
要将 Hadoop 本地库与 Alluxio HDFS 底层文件系统一起使用，首先[按照此页面上的说明](https://hadoop.apache.org/docs/current/hadoop-project-dist/hadoop-common/NativeLibraries.html)在 Alluxio 节点上安装本地库。\
一旦在机器上安装了 Hadoop 本地库，请通过在 `conf/alluxio-env.sh` 中添加以下行来更新 Alluxio 启动 Java 参数：

```sh
ALLUXIO_JAVA_OPTS+=" -Djava.library.path=<local_path_containing_hadoop_native_library> "
```

确保重新启动 Alluxio 服务以使更改生效。

### \[实验性] HDFS 回收站功能

HDFS 默认支持回收站功能。\
当删除 HDFS 文件时，它将被移动到回收站目录，后续被实际删除。\
用户可以通过设置来启用 HDFS 回收站功能 `alluxio.underfs.hdfs.trash.enabled=true`。

如果启用了该功能，当用户删除一个通过 Alluxio 存储在 HDFS 中的文件时，\
Alluxio 将尝试将其移动到 HDFS 回收站目录，而不是直接从 HDFS 中删除它。\
请注意，必须在 `core-site.xml` 中配置 HDFS 以启用回收站功能。\
如果在 HDFS 中未启用回收站功能，则 Alluxio 将直接删除文件，而不考虑此配置。
