# GCS

本指南介绍了如何配置 Alluxio，将 [Google Cloud Storage (GCS)](https://cloud.google.com/storage/)作为底层存储系统使用。

Google Cloud Storage (GCS) 是 Google Cloud Platform (GCP) 提供的一个可扩展且耐久性高的对象存储服务。 它允许用户存储和检索各种类型的数据，包括非结构化数据和结构化数据。

有关 GCS 的更多信息，请参阅 [文档](https://cloud.google.com/storage/docs)。

## 先决条件

开始部署前，请参阅 [先决条件](https://documentation.alluxio.io/ee-ai-cn/ai-3.3/storage-overview#先决条件)。

将 GCS 与 Alluxio 共同使用前的准备：

| `<GCS_BUCKET>`    | [在 Google Cloud 账户中创建一个新的存储桶](https://cloud.google.com/storage/docs/creating-buckets) 或者使用现有的存储桶 |
| ----------------- | ------------------------------------------------------------------------------------------------ |
| `<GCS_DIRECTORY>` | 希望在存储桶中使用的目录，可以创建新目录或使用现有目录                                                                      |

Alluxio 提供两种 GCS 访问方式。GCS 版本 1 基于针对 AWS S3 设计的 [jets3t](http://www.jets3t.org/) 库实现。 因此，它只接受 Google Cloud Storage 互操作访问/密钥对，允许对 Google Cloud 项目内的所有 Google Cloud Storage 进行完全访问。 在使用互操作密钥时，不能定义任何权限或进行访问控制。 Google 互操作 API 与 jets3t 库的结合对默认的 GCS UFS 模块的性能有影响。

默认的 GCS UFS 模块（GCS 版本 2）基于 Google Cloud API 实现，接受 [Google 应用凭证](https://cloud.google.com/docs/authentication/getting-started)。 在创建应用凭证时，可以通过定义细粒度的权限来限制对特定存储桶的访问。 与 GCS 版本 1 相比，版本 2的元数据和 I/O 性能更好。

## 基本设置

使用 [挂载表操作](https://documentation.alluxio.io/ee-ai-cn/ai-3.3/feature/alluxio-namespace-and-under-file-system-namespaces#挂载表操作) 添加新的挂载点，指定创建挂载点的Alluxio 路径，并将 GCS 路径指定为 UFS URI。 凭证和配置选项也可以作为挂载命令的一部分，通过指定 `--option` 标签来进行配置，详见 [配置挂载点](https://documentation.alluxio.io/ee-ai-cn/ai-3.3/feature/alluxio-namespace-and-under-file-system-namespaces#对不同挂载点使用不同的配置)。

选择所偏好的 GCS UFS 版本并提供相应的 Google 凭证。

<details>

<summary>GCS version 2</summary>

按照 GCS v2 的方式将 `gs://<GCS_BUCKET>/<GCS_DIRECTORY>` 挂载到 `/gs`的命令示例如下：

```shell
bin/alluxio mount add --path /gs/ --ufs-uri gs://<GCS_BUCKET>/<GCS_DIRECTORY> \
  --option fs.gcs.credential.path=/path/to/<google_application_credentials>.json
```

属性键 `fs.gcs.credential.path` 提供了 Google 应用凭证 JSON 文件的路径。 请注意，Google 应用凭证 JSON 文件应置于所有 Alluxio 节点的同一路径下。 如果运行 Alluxio 进程的节点已经包含 GCS 凭证，则可能不需要该属性，但还是建议明确设置这一属性。

</details>

<details>

<summary>GCS version1</summary>

按照 GCS v1 的方式将 `gs://<GCS_BUCKET>/<GCS_DIRECTORY>` 挂载到 `/gs`的命令示例如下：

```shell
bin/alluxio mount add --path /gs/ --ufs-uri gs://<GCS_BUCKET>/<GCS_DIRECTORY> \
  --option alluxio.underfs.gcs.version=1 --option fs.gcs.accessKeyId=<GCS_ACCESS_KEY_ID> \
  --option fs.gcs.secretAccessKey=<GCS_SECRET_ACCESS_KEY>
```

* 第一个属性键告诉 Alluxio 加载 GCS 版本1的 UFS 模块，该模块使用 [jets3t](http://www.jets3t.org/) 库。
* 将 `<GCS_ACCESS_KEY_ID>` 和 `<GCS_ACCESS_KEY_ID>` 替换为实际的 [GCS 互操作存储访问密钥](https://console.cloud.google.com/storage/settings)，或其他包含凭证的环境变量。

注：GCS 互操作性是默认禁用的。请点击 [GCS 设置](https://console.cloud.google.com/storage/settings) 中的互操作性选项卡并启用此功能。点击`Create a new key`获取访问密钥和密钥对。

</details>

## 进阶设置

### 自定义目录后缀

在 GCS 中，目录表示为以指定后缀命名的零字节对象。 可以使用配置参数 `alluxio.underfs.gcs.directory.suffix` 来更新目录后缀。

## GCS 在 GCS 中，目录表示为以指定后缀命名的零字节对象。可以使用配置参数 `alluxio.underfs.gcs.directory.suffix` 来更新目录后缀。

如果启用了 Alluxio 安全性，Alluxio 将执行从底层对象存储继承的访问控制。

在 Alluxio 配置中指定的 GCS 凭证代表一个 GCS 用户。 GCS 服务后端会检查用户对存储桶和对象的权限以进行访问控制。 如果给定的 GCS 用户没有对指定存储桶的正确访问权限，则会抛出拒绝访问的报错。 当启用 Alluxio 安全性时，Alluxio 会在首次将元数据加载到 Alluxio 命名空间时，将存储桶的 ACL 加载到 Alluxio 权限中。

### 从 GCS ACL 到 Alluxio 权限的映射

Alluxio 检查 GCS 存储桶的读/写 ACL 以确定所有者对 Alluxio 文件的权限模式。 例如，如果 GCS 用户对底层存储桶具有只读访问权限，则挂载的目录和文件将具有`0500`模式。 如果 GCS 用户对底层存储桶具有完全访问权限，则挂载的目录和文件将具有`0700`模式。

### 从 GCS 用户到 Alluxio 文件所有者（仅限 GCS 版本1）

默认情况下，Alluxio 尝试从凭证中提取 GCS 用户 ID。 可以选择性地使用`alluxio.underfs.gcs.owner.id.to.username.mapping`来指定预设的GCS 所有者 ID 到 Alluxio 用户名的静态映射，格式为 `id1=user1;id2=user2`。 Google Cloud Storage ID 可以在控制台地址中找到。 请使用`Owners`部分的 ID。

### 通过代理访问GCS(仅限 GCS 版本2）

如果 Alluxio 集群位于公司代理或防火墙后面，默认设置下 Alluxio 与 GCS 集成可能无法访问网络。

在启动 Alluxio coordinator 和 worker 之前，请将以下 Java 选项添加到 `conf/alluxio-env.sh`中：

```sh
ALLUXIO_COORDINATOR_JAVA_OPTS+=" -Dhttps.proxyHost=<proxy_host> -Dhttps.proxyPort=<proxy_port> -Dhttp.proxyHost=<proxy_host> -Dhttp.proxyPort=<proxy_port> -Dhttp.nonProxyHosts=<non_proxy_host>"
ALLUXIO_WORKER_JAVA_OPTS+=" -Dhttps.proxyHost=<proxy_host> -Dhttps.proxyPort=<proxy_port> -Dhttp.proxyHost=<proxy_host> -Dhttp.proxyPort=<proxy_port> -Dhttp.nonProxyHosts=<non_proxy_host>"
```

`http.nonProxyHosts`的示例值是`localhost|127.*|[::1]|192.168.0.0/16`。

如果代理需要用户名和密码，请添加 `http.proxyUser`、`https.proxyUser`、 `http.proxyPassword` 和 `https.proxyPassword`Java 选项。
